Compare commits
5 Commits
v1.5.0
...
v1.7.0-bet
| Author | SHA1 | Date | |
|---|---|---|---|
| 91c0a2d9d9 | |||
| 0ff0c0d55e | |||
| 1358e17ac3 | |||
| 4ce1578bb5 | |||
| 72dac40753 |
@@ -1,11 +1,9 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
require('config.php');
|
require('config.php');
|
||||||
require('EpiApi.php');
|
require('EpiApi.php');
|
||||||
require('vendor/autoload.php');
|
require('vendor/autoload.php');
|
||||||
|
|
||||||
$Epi = new Epirent();
|
$Epi = new Epirent();
|
||||||
|
|
||||||
?>
|
?>
|
||||||
|
|
||||||
|
|
||||||
@@ -22,54 +20,184 @@ $Epi = new Epirent();
|
|||||||
<link rel="stylesheet" href="vendor/twbs/bootstrap/dist/css/bootstrap.min.css" >
|
<link rel="stylesheet" href="vendor/twbs/bootstrap/dist/css/bootstrap.min.css" >
|
||||||
<script src="scripts/jquery-3.5.1.min.js"></script>
|
<script src="scripts/jquery-3.5.1.min.js"></script>
|
||||||
<link href="css/sticky-footer.css" rel="stylesheet">
|
<link href="css/sticky-footer.css" rel="stylesheet">
|
||||||
<!-- HTML5 shim and Respond.js for IE8 support of HTML5 elements and media queries -->
|
<script src="https://kit.fontawesome.com/93d71de8bc.js" crossorigin="anonymous"></script>
|
||||||
<!-- WARNING: Respond.js doesn't work if you view the page via file:// -->
|
|
||||||
<!--[if lt IE 9]>
|
|
||||||
<script src="https://oss.maxcdn.com/html5shiv/3.7.3/html5shiv.min.js"></script>
|
|
||||||
<script src="https://oss.maxcdn.com/respond/1.4.2/respond.min.js"></script>
|
|
||||||
<![endif]-->
|
|
||||||
|
|
||||||
<script type="text/javascript">
|
<script type="text/javascript">
|
||||||
// Dynamische Höhe: Wrapper exakt bis Viewport-Unterkante
|
// === Höhe der Scroll-Container bis Viewport-Ende anpassen ===
|
||||||
function sizeScrollContainers() {
|
function sizeScrollContainers() {
|
||||||
$('.tableFixHead').each(function () {
|
$('.tableFixHead').each(function () {
|
||||||
const rect = this.getBoundingClientRect();
|
const rect = this.getBoundingClientRect();
|
||||||
const bottomMargin = 16; // kleiner Abstand zum Rand
|
const bottomMargin = 16;
|
||||||
const available = window.innerHeight - rect.top - bottomMargin;
|
const available = window.innerHeight - rect.top - bottomMargin;
|
||||||
this.style.maxHeight = (available > 120 ? available : 120) + 'px';
|
this.style.maxHeight = (available > 120 ? available : 120) + 'px';
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
// Lädt tbody via AJAX und erhält die Scrollposition relativ zum unteren Rand
|
// === Scroll-/Interaktionsstatus je Scroller ===
|
||||||
function smartLoad($scroller, $target, url, intervalMs) {
|
const scrollState = new WeakMap(); // { userActive:boolean, autoTimer:number|null, loopHeight:number }
|
||||||
const scroller = $scroller.get(0);
|
|
||||||
// Abstand vom unteren Rand merken (wichtiger als absolute scrollTop)
|
function ensureState(el) {
|
||||||
const fromBottomBefore = scroller.scrollHeight - scroller.clientHeight - scroller.scrollTop;
|
if (!scrollState.get(el)) scrollState.set(el, { userActive: false, autoTimer: null, loopHeight: 0 });
|
||||||
|
return scrollState.get(el);
|
||||||
|
}
|
||||||
|
|
||||||
|
function attachScrollGuards($scroller) {
|
||||||
|
const el = $scroller.get(0);
|
||||||
|
if (!el || el.__guardsBound) return;
|
||||||
|
const state = ensureState(el);
|
||||||
|
|
||||||
|
const markActive = () => {
|
||||||
|
state.userActive = true;
|
||||||
|
clearTimeout(state._quietT);
|
||||||
|
state._quietT = setTimeout(() => { state.userActive = false; }, 800);
|
||||||
|
stopAutoScroll($scroller);
|
||||||
|
};
|
||||||
|
|
||||||
|
$scroller.on('wheel touchstart touchmove keydown mousedown mouseenter', markActive);
|
||||||
|
$scroller.on('mouseleave', () => setTimeout(() => maybeStartAutoScroll($scroller), 600));
|
||||||
|
el.__guardsBound = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// === Loop aufbauen: nahtloses Doppel nur bei Bedarf ===
|
||||||
|
// Klont den ersten <tbody> als __loopClone ans Tabellenende, wenn Inhalt > Sichtbereich.
|
||||||
|
function buildSeamlessLoop($table, $scroller) {
|
||||||
|
$table.find('tbody.__loopClone').remove();
|
||||||
|
|
||||||
|
const $main = $table.find('tbody').first();
|
||||||
|
const scEl = $scroller.get(0);
|
||||||
|
const st = ensureState(scEl);
|
||||||
|
|
||||||
|
if ($main.length === 0 || $main.children().length === 0) {
|
||||||
|
st.loopHeight = 0;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const mainH = $main.get(0).offsetHeight;
|
||||||
|
const needScroll = mainH > scEl.clientHeight + 1;
|
||||||
|
|
||||||
|
if (!needScroll) {
|
||||||
|
st.loopHeight = 0;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const $clone = $main.clone(false, false).addClass('__loopClone').attr('aria-hidden', 'true');
|
||||||
|
$table.append($clone);
|
||||||
|
st.loopHeight = mainH; // Höhe des Original-Inhalts als Loop-Länge
|
||||||
|
}
|
||||||
|
|
||||||
|
// === Auto-Scroll (nahtlos) ===
|
||||||
|
function startAutoScroll($scroller, speedPx = 1, stepMs = 40) {
|
||||||
|
const el = $scroller.get(0);
|
||||||
|
const st = ensureState(el);
|
||||||
|
|
||||||
|
if (st.autoTimer) return; // schon aktiv
|
||||||
|
if (st.loopHeight <= 0) return; // kein Overflow => nicht scrollen
|
||||||
|
|
||||||
|
const tick = () => {
|
||||||
|
if (st.userActive) { stopAutoScroll($scroller); return; }
|
||||||
|
el.scrollTop += speedPx;
|
||||||
|
// Nahtlos: sobald wir das Ende des Original-Blocks überschreiten, ziehen wir loopHeight ab
|
||||||
|
if (el.scrollTop >= st.loopHeight) {
|
||||||
|
el.scrollTop -= st.loopHeight;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
st.autoTimer = setInterval(tick, stepMs);
|
||||||
|
}
|
||||||
|
|
||||||
|
function stopAutoScroll($scroller) {
|
||||||
|
const el = $scroller.get(0);
|
||||||
|
const st = ensureState(el);
|
||||||
|
if (st.autoTimer) {
|
||||||
|
clearInterval(st.autoTimer);
|
||||||
|
st.autoTimer = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function maybeStartAutoScroll($scroller) {
|
||||||
|
const el = $scroller.get(0);
|
||||||
|
const st = ensureState(el);
|
||||||
|
if (st.userActive) return;
|
||||||
|
if (st.loopHeight > 0) startAutoScroll($scroller, 1, 80);
|
||||||
|
else stopAutoScroll($scroller);
|
||||||
|
}
|
||||||
|
|
||||||
|
// === AJAX-Reload: relative Position innerhalb der Loop erhalten ===
|
||||||
|
// Wir merken die Position modulo loopHeight; nach dem Reload setzen wir proportional um.
|
||||||
|
function smartLoad($scroller, $table, $target, url, intervalMs) {
|
||||||
|
const scEl = $scroller.get(0);
|
||||||
|
const st = ensureState(scEl);
|
||||||
|
|
||||||
|
const oldLoop = st.loopHeight > 0 ? st.loopHeight : Math.max(1, scEl.scrollHeight - scEl.clientHeight);
|
||||||
|
const posInLoop = st.loopHeight > 0 ? (scEl.scrollTop % oldLoop) : scEl.scrollTop;
|
||||||
|
const posRatio = Math.min(1, posInLoop / oldLoop);
|
||||||
|
|
||||||
$target.load(url, function () {
|
$target.load(url, function () {
|
||||||
// Nach dem Ersetzen: dieselbe Distanz zum unteren Rand wiederherstellen
|
// Loop neu bewerten/aufbauen
|
||||||
const newScrollTop = scroller.scrollHeight - scroller.clientHeight - fromBottomBefore;
|
buildSeamlessLoop($table, $scroller);
|
||||||
// Begrenzen, falls weniger Inhalt
|
|
||||||
scroller.scrollTop = Math.max(0, newScrollTop);
|
|
||||||
|
|
||||||
// Nächstes Update planen
|
if (st.loopHeight > 0) {
|
||||||
setTimeout(function () {
|
// Neue relative Position setzen (proportional)
|
||||||
smartLoad($scroller, $target, url, intervalMs);
|
const newPos = Math.floor(posRatio * st.loopHeight);
|
||||||
}, intervalMs);
|
if (Math.abs(scEl.scrollTop - newPos) > 1) {
|
||||||
|
// rAF für flüssiges Setzen außerhalb des load()-Layouts
|
||||||
|
requestAnimationFrame(() => { scEl.scrollTop = newPos; });
|
||||||
|
}
|
||||||
|
// Auto-Scroll (wieder) starten
|
||||||
|
stopAutoScroll($scroller);
|
||||||
|
startAutoScroll($scroller, 1, 80);
|
||||||
|
} else {
|
||||||
|
// kein Overflow -> ganz oben und Auto-Scroll aus
|
||||||
|
if (scEl.scrollTop !== 0) requestAnimationFrame(() => { scEl.scrollTop = 0; });
|
||||||
|
stopAutoScroll($scroller);
|
||||||
|
}
|
||||||
|
|
||||||
|
setTimeout(() => smartLoad($scroller, $table, $target, url, intervalMs), intervalMs);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// === Initialisierung ===
|
||||||
$(document).ready(function () {
|
$(document).ready(function () {
|
||||||
sizeScrollContainers();
|
sizeScrollContainers();
|
||||||
$(window).on('resize', sizeScrollContainers);
|
$(window).on('resize', function () {
|
||||||
|
sizeScrollContainers();
|
||||||
|
// Nach Layoutwechsel neu entscheiden
|
||||||
|
['#checkout', '#checkin', '#aufgaben'].forEach(prefix => {
|
||||||
|
const $scroller = $(`${prefix}-scroll`);
|
||||||
|
const $table = $(`${prefix}-table`);
|
||||||
|
buildSeamlessLoop($table, $scroller);
|
||||||
|
maybeStartAutoScroll($scroller);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
// Initial laden + Auto-Refresh, jeweils eigener Scroller
|
// Guards pro Scroller
|
||||||
smartLoad($('#checkout-scroll'), $('#getCheckOutTableHolder'), 'sources/getCheckOutTable.php', 5000);
|
attachScrollGuards($('#checkout-scroll'));
|
||||||
smartLoad($('#checkin-scroll'), $('#getCheckInTableHolder'), 'sources/getCheckInTable.php', 5000);
|
attachScrollGuards($('#checkin-scroll'));
|
||||||
smartLoad($('#aufgaben-scroll'), $('#AufgabenTableHolder'), 'sources/getAufgabenTable.php', 30000);
|
attachScrollGuards($('#aufgaben-scroll'));
|
||||||
|
|
||||||
|
// Erstladen je Tabelle: laden -> Loop bauen -> ggf. Auto-Scroll -> zyklisch refreshen
|
||||||
|
function initOne(scrollerSel, tableSel, tbodySel, url, ms) {
|
||||||
|
const $scroller = $(scrollerSel);
|
||||||
|
const $table = $(tableSel);
|
||||||
|
const $target = $(tbodySel);
|
||||||
|
|
||||||
|
$target.load(url, function () {
|
||||||
|
buildSeamlessLoop($table, $scroller);
|
||||||
|
maybeStartAutoScroll($scroller);
|
||||||
|
setTimeout(() => smartLoad($scroller, $table, $target, url, ms), ms);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
initOne('#checkout-scroll', '#checkout-table', '#getCheckOutTableHolder', 'sources/getCheckOutTable.php', 5000);
|
||||||
|
initOne('#checkin-scroll', '#checkin-table', '#getCheckInTableHolder', 'sources/getCheckInTable.php', 5000);
|
||||||
|
initOne('#aufgaben-scroll', '#aufgaben-table', '#AufgabenTableHolder', 'sources/getAufgabenTable.php', 30000);
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<style>
|
<style>
|
||||||
/* Scroll-Wrapper je Tabelle */
|
/* Scroll-Wrapper je Tabelle */
|
||||||
.tableFixHead {
|
.tableFixHead {
|
||||||
@@ -98,7 +226,7 @@ $Epi = new Epirent();
|
|||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
</head>
|
</head>
|
||||||
<body style="background-color: black;">
|
<body style="margin-bottom:0px; background-color: black;">
|
||||||
|
|
||||||
<div class="container-fluid">
|
<div class="container-fluid">
|
||||||
<div class="row">
|
<div class="row">
|
||||||
@@ -111,14 +239,38 @@ $Epi = new Epirent();
|
|||||||
<th scope="col">#</th>
|
<th scope="col">#</th>
|
||||||
<th scope="col">Kunde</th>
|
<th scope="col">Kunde</th>
|
||||||
<th scope="col">Event</th>
|
<th scope="col">Event</th>
|
||||||
<th scope="col">Dispo-Start<br><i>VB-Start</i></th>
|
|
||||||
<?php
|
|
||||||
|
|
||||||
if(!HideCheckInTimeOnCheckout){
|
<?php
|
||||||
echo "<th scope='col'>Dispo-Ende<br><i>VB-Ende</i></th>";
|
if(ShowCheckoutTimeOnCheckout || ShowVorbereitungTimeOnCheckout||ShowPackagingTimeOnCheckout || ShowDeliveryTimeOnCheckout){
|
||||||
|
echo '<th scope="col">';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(ShowCheckoutTimeOnCheckout){
|
||||||
|
echo "Dispo-Start";
|
||||||
|
}
|
||||||
|
if(ShowVorbereitungTimeOnCheckout){
|
||||||
|
if(ShowCheckoutTimeOnCheckout){echo "<br>";}
|
||||||
|
echo "VB-Start";
|
||||||
|
}
|
||||||
|
if(ShowPackagingTimeOnCheckout){
|
||||||
|
if(ShowCheckoutTimeOnCheckout||ShowVorbereitungTimeOnCheckout){echo "<br>";}
|
||||||
|
echo "Packen";
|
||||||
|
}
|
||||||
|
if(ShowDeliveryTimeOnCheckout){
|
||||||
|
if(ShowCheckoutTimeOnCheckout || ShowVorbereitungTimeOnCheckout||ShowPackagingTimeOnCheckout){echo "<br>";}
|
||||||
|
echo "Liefern";
|
||||||
|
}
|
||||||
|
if(ShowCheckoutTimeOnCheckout || ShowVorbereitungTimeOnCheckout||ShowPackagingTimeOnCheckout || ShowDeliveryTimeOnCheckout){
|
||||||
|
echo '</th>';
|
||||||
|
}
|
||||||
|
|
||||||
?>
|
?>
|
||||||
<th scope="col">Status</th>
|
<th scope="col">Status</th>
|
||||||
|
<?php
|
||||||
|
if(ShowShippingIcons){
|
||||||
|
echo "<th scope='col'>Shipping</th>";
|
||||||
|
}
|
||||||
|
?>
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody id="getCheckOutTableHolder"></tbody>
|
<tbody id="getCheckOutTableHolder"></tbody>
|
||||||
@@ -134,15 +286,40 @@ $Epi = new Epirent();
|
|||||||
<tr>
|
<tr>
|
||||||
<th scope="col">#</th>
|
<th scope="col">#</th>
|
||||||
<th scope="col">Kunde</th>
|
<th scope="col">Kunde</th>
|
||||||
<th scope="col">Event</th>
|
<th scope="col">Event</th> <?php
|
||||||
<?php
|
if(ShowCheckInTimeOnCheckin || ShowNachbereitungTimeOnCheckin ||ShowRePackagingTimeOnCheckin || ShowReDeliveryTimeOnCheckin){
|
||||||
|
echo '<th scope="col">';
|
||||||
|
}
|
||||||
|
|
||||||
if(!HideCheckOutTimeOnCheckin){
|
if(ShowCheckInTimeOnCheckin){
|
||||||
echo "<th scope='col'>Dispo-Start<br><i>RP-Start</i></th>";
|
echo "Dispo-Ende";
|
||||||
|
}
|
||||||
|
if(ShowNachbereitungTimeOnCheckin){
|
||||||
|
if(ShowCheckInTimeOnCheckin){echo "<br>";}
|
||||||
|
echo "Nachbereitung";
|
||||||
|
}
|
||||||
|
if(ShowRePackagingTimeOnCheckin){
|
||||||
|
if(ShowCheckInTimeOnCheckin||ShowNachbereitungTimeOnCheckin){echo "<br>";}
|
||||||
|
echo "Zurückpacken";
|
||||||
|
}
|
||||||
|
if(ShowReDeliveryTimeOnCheckin){
|
||||||
|
if(ShowCheckInTimeOnCheckin || ShowNachbereitungTimeOnCheckin||ShowRePackagingTimeOnCheckin){echo "<br>";}
|
||||||
|
echo "Rückliefern";
|
||||||
|
}
|
||||||
|
if(ShowCheckInTimeOnCheckin || ShowNachbereitungTimeOnCheckin||ShowRePackagingTimeOnCheckin || ShowReDeliveryTimeOnCheckin){
|
||||||
|
echo '</th>';
|
||||||
|
}
|
||||||
|
|
||||||
|
?>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<th scope="col">Status</th>
|
||||||
|
<?php
|
||||||
|
if(ShowShippingIcons){
|
||||||
|
echo "<th scope='col'>Shipping</th>";
|
||||||
}
|
}
|
||||||
?>
|
?>
|
||||||
<th scope="col">Dispo-Ende<br><i>RP-Ende</i></th>
|
|
||||||
<th scope="col">Status</th>
|
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody id="getCheckInTableHolder"></tbody>
|
<tbody id="getCheckInTableHolder"></tbody>
|
||||||
@@ -182,7 +359,6 @@ $Epi = new Epirent();
|
|||||||
|
|
||||||
|
|
||||||
<!-- jQuery (necessary for Bootstrap's JavaScript plugins) -->
|
<!-- jQuery (necessary for Bootstrap's JavaScript plugins) -->
|
||||||
<script src="https://code.jquery.com/jquery-1.12.4.min.js" integrity="sha384-nvAa0+6Qg9clwYCGGPpDQLVpLNn0fRaROjHqs13t4Ggj3Ez50XnGQqc/r8MhnRDZ" crossorigin="anonymous"></script>
|
|
||||||
<!-- Include all compiled plugins (below), or include individual files as needed -->
|
<!-- Include all compiled plugins (below), or include individual files as needed -->
|
||||||
<script src="vendor/twbs/bootstrap/dist/js/bootstrap.min.js" integrity="sha384-aJ21OjlMXNL5UyIl/XNwTMqvzeRMZH2w8c5cRVpzpU8Y5bApTppSuUkhZXN0VxHd" crossorigin="anonymous"></script>
|
<script src="vendor/twbs/bootstrap/dist/js/bootstrap.min.js" integrity="sha384-aJ21OjlMXNL5UyIl/XNwTMqvzeRMZH2w8c5cRVpzpU8Y5bApTppSuUkhZXN0VxHd" crossorigin="anonymous"></script>
|
||||||
</body>
|
</body>
|
||||||
|
|||||||
344
Packmonitor.php
344
Packmonitor.php
@@ -1,9 +1,4 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
|
|
||||||
error_reporting(E_ALL);
|
|
||||||
|
|
||||||
|
|
||||||
require('config.php');
|
require('config.php');
|
||||||
require('EpiApi.php');
|
require('EpiApi.php');
|
||||||
require('vendor/autoload.php');
|
require('vendor/autoload.php');
|
||||||
@@ -18,139 +13,326 @@ $Epi = new Epirent();
|
|||||||
<meta charset="utf-8">
|
<meta charset="utf-8">
|
||||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||||
<!-- The above 3 meta tags *must* come first in the head; any other head content must come *after* these tags -->
|
|
||||||
<title>Packmonitor</title>
|
<title>Packmonitor</title>
|
||||||
|
|
||||||
<!-- Bootstrap -->
|
<!-- Bootstrap -->
|
||||||
<link rel="stylesheet" href="vendor/twbs/bootstrap/dist/css/bootstrap.min.css">
|
<link rel="stylesheet" href="vendor/twbs/bootstrap/dist/css/bootstrap.min.css">
|
||||||
<script src="scripts/jquery-3.5.1.min.js"></script>
|
<script src="scripts/jquery-3.5.1.min.js"></script>
|
||||||
<link href="css/sticky-footer.css" rel="stylesheet">
|
<link href="css/sticky-footer.css" rel="stylesheet">
|
||||||
<!-- HTML5 shim and Respond.js for IE8 support of HTML5 elements and media queries -->
|
<script src="https://kit.fontawesome.com/93d71de8bc.js" crossorigin="anonymous"></script>
|
||||||
<!-- WARNING: Respond.js doesn't work if you view the page via file:// -->
|
|
||||||
<!--[if lt IE 9]>
|
|
||||||
<script src="https://oss.maxcdn.com/html5shiv/3.7.3/html5shiv.min.js"></script>
|
|
||||||
<script src="https://oss.maxcdn.com/respond/1.4.2/respond.min.js"></script>
|
|
||||||
<![endif]-->
|
|
||||||
|
|
||||||
<script type="text/javascript">
|
<script type="text/javascript">
|
||||||
|
// === Höhe der Scroll-Container bis Viewport-Ende anpassen ===
|
||||||
|
function sizeScrollContainers() {
|
||||||
|
$('.tableFixHead').each(function () {
|
||||||
|
const rect = this.getBoundingClientRect();
|
||||||
|
const bottomMargin = 16;
|
||||||
|
const available = window.innerHeight - rect.top - bottomMargin;
|
||||||
|
this.style.maxHeight = (available > 120 ? available : 120) + 'px';
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// === Scroll-/Interaktionsstatus je Scroller ===
|
||||||
|
const scrollState = new WeakMap(); // { userActive:boolean, autoTimer:number|null, loopHeight:number }
|
||||||
|
|
||||||
|
function ensureState(el) {
|
||||||
|
if (!scrollState.get(el)) scrollState.set(el, { userActive: false, autoTimer: null, loopHeight: 0 });
|
||||||
|
return scrollState.get(el);
|
||||||
|
}
|
||||||
|
|
||||||
|
function attachScrollGuards($scroller) {
|
||||||
|
const el = $scroller.get(0);
|
||||||
|
if (!el || el.__guardsBound) return;
|
||||||
|
const state = ensureState(el);
|
||||||
|
|
||||||
|
const markActive = () => {
|
||||||
|
state.userActive = true;
|
||||||
|
clearTimeout(state._quietT);
|
||||||
|
state._quietT = setTimeout(() => { state.userActive = false; }, 800);
|
||||||
|
stopAutoScroll($scroller);
|
||||||
|
};
|
||||||
|
|
||||||
|
$scroller.on('wheel touchstart touchmove keydown mousedown mouseenter', markActive);
|
||||||
|
$scroller.on('mouseleave', () => setTimeout(() => maybeStartAutoScroll($scroller), 600));
|
||||||
|
el.__guardsBound = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// === Loop aufbauen: nahtloses Doppel nur bei Bedarf ===
|
||||||
|
// Klont den ersten <tbody> als __loopClone ans Tabellenende, wenn Inhalt > Sichtbereich.
|
||||||
|
function buildSeamlessLoop($table, $scroller) {
|
||||||
|
$table.find('tbody.__loopClone').remove();
|
||||||
|
|
||||||
|
const $main = $table.find('tbody').first();
|
||||||
|
const scEl = $scroller.get(0);
|
||||||
|
const st = ensureState(scEl);
|
||||||
|
|
||||||
|
if ($main.length === 0 || $main.children().length === 0) {
|
||||||
|
st.loopHeight = 0;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const mainH = $main.get(0).offsetHeight;
|
||||||
|
const needScroll = mainH > scEl.clientHeight + 1;
|
||||||
|
|
||||||
|
if (!needScroll) {
|
||||||
|
st.loopHeight = 0;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const $clone = $main.clone(false, false).addClass('__loopClone').attr('aria-hidden', 'true');
|
||||||
|
$table.append($clone);
|
||||||
|
st.loopHeight = mainH; // Höhe des Original-Inhalts als Loop-Länge
|
||||||
|
}
|
||||||
|
|
||||||
|
// === Auto-Scroll (nahtlos) ===
|
||||||
|
function startAutoScroll($scroller, speedPx = 1, stepMs = 40) {
|
||||||
|
const el = $scroller.get(0);
|
||||||
|
const st = ensureState(el);
|
||||||
|
|
||||||
|
if (st.autoTimer) return; // schon aktiv
|
||||||
|
if (st.loopHeight <= 0) return; // kein Overflow => nicht scrollen
|
||||||
|
|
||||||
|
const tick = () => {
|
||||||
|
if (st.userActive) { stopAutoScroll($scroller); return; }
|
||||||
|
el.scrollTop += speedPx;
|
||||||
|
// Nahtlos: sobald wir das Ende des Original-Blocks überschreiten, ziehen wir loopHeight ab
|
||||||
|
if (el.scrollTop >= st.loopHeight) {
|
||||||
|
el.scrollTop -= st.loopHeight;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
st.autoTimer = setInterval(tick, stepMs);
|
||||||
|
}
|
||||||
|
|
||||||
|
function stopAutoScroll($scroller) {
|
||||||
|
const el = $scroller.get(0);
|
||||||
|
const st = ensureState(el);
|
||||||
|
if (st.autoTimer) {
|
||||||
|
clearInterval(st.autoTimer);
|
||||||
|
st.autoTimer = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function maybeStartAutoScroll($scroller) {
|
||||||
|
const el = $scroller.get(0);
|
||||||
|
const st = ensureState(el);
|
||||||
|
if (st.userActive) return;
|
||||||
|
if (st.loopHeight > 0) startAutoScroll($scroller, 1, 40);
|
||||||
|
else stopAutoScroll($scroller);
|
||||||
|
}
|
||||||
|
|
||||||
|
// === AJAX-Reload: relative Position innerhalb der Loop erhalten ===
|
||||||
|
// Wir merken die Position modulo loopHeight; nach dem Reload setzen wir proportional um.
|
||||||
|
function smartLoad($scroller, $table, $target, url, intervalMs) {
|
||||||
|
const scEl = $scroller.get(0);
|
||||||
|
const st = ensureState(scEl);
|
||||||
|
|
||||||
|
const oldLoop = st.loopHeight > 0 ? st.loopHeight : Math.max(1, scEl.scrollHeight - scEl.clientHeight);
|
||||||
|
const posInLoop = st.loopHeight > 0 ? (scEl.scrollTop % oldLoop) : scEl.scrollTop;
|
||||||
|
const posRatio = Math.min(1, posInLoop / oldLoop);
|
||||||
|
|
||||||
|
$target.load(url, function () {
|
||||||
|
// Loop neu bewerten/aufbauen
|
||||||
|
buildSeamlessLoop($table, $scroller);
|
||||||
|
|
||||||
|
if (st.loopHeight > 0) {
|
||||||
|
// Neue relative Position setzen (proportional)
|
||||||
|
const newPos = Math.floor(posRatio * st.loopHeight);
|
||||||
|
if (Math.abs(scEl.scrollTop - newPos) > 1) {
|
||||||
|
// rAF für flüssiges Setzen außerhalb des load()-Layouts
|
||||||
|
requestAnimationFrame(() => { scEl.scrollTop = newPos; });
|
||||||
|
}
|
||||||
|
// Auto-Scroll (wieder) starten
|
||||||
|
stopAutoScroll($scroller);
|
||||||
|
startAutoScroll($scroller, 1, 40);
|
||||||
|
} else {
|
||||||
|
// kein Overflow -> ganz oben und Auto-Scroll aus
|
||||||
|
if (scEl.scrollTop !== 0) requestAnimationFrame(() => { scEl.scrollTop = 0; });
|
||||||
|
stopAutoScroll($scroller);
|
||||||
|
}
|
||||||
|
|
||||||
|
setTimeout(() => smartLoad($scroller, $table, $target, url, intervalMs), intervalMs);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// === Initialisierung ===
|
||||||
$(document).ready(function () {
|
$(document).ready(function () {
|
||||||
refreshCheckOutTable();
|
sizeScrollContainers();
|
||||||
refreshCheckInTable();
|
$(window).on('resize', function () {
|
||||||
|
sizeScrollContainers();
|
||||||
|
// Nach Layoutwechsel neu entscheiden (nur 2 Tabellen)
|
||||||
|
['#checkout', '#checkin'].forEach(prefix => {
|
||||||
|
const $scroller = $(`${prefix}-scroll`);
|
||||||
|
const $table = $(`${prefix}-table`);
|
||||||
|
buildSeamlessLoop($table, $scroller);
|
||||||
|
maybeStartAutoScroll($scroller);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
function refreshCheckOutTable() {
|
// Guards pro Scroller (nur 2)
|
||||||
$('#getCheckOutTableHolder').load('sources/getCheckOutTable.php', function () {
|
attachScrollGuards($('#checkout-scroll'));
|
||||||
setTimeout(refreshCheckOutTable, 5000);
|
attachScrollGuards($('#checkin-scroll'));
|
||||||
});
|
|
||||||
}
|
// Erstladen je Tabelle: laden -> Loop bauen -> ggf. Auto-Scroll -> zyklisch refreshen
|
||||||
function refreshCheckInTable() {
|
function initOne(scrollerSel, tableSel, tbodySel, url, ms) {
|
||||||
$('#getCheckInTableHolder').load('sources/getCheckInTable.php', function () {
|
const $scroller = $(scrollerSel);
|
||||||
setTimeout(refreshCheckInTable, 5000);
|
const $table = $(tableSel);
|
||||||
|
const $target = $(tbodySel);
|
||||||
|
|
||||||
|
$target.load(url, function () {
|
||||||
|
buildSeamlessLoop($table, $scroller);
|
||||||
|
maybeStartAutoScroll($scroller);
|
||||||
|
setTimeout(() => smartLoad($scroller, $table, $target, url, ms), ms);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
initOne('#checkout-scroll', '#checkout-table', '#getCheckOutTableHolder', 'sources/getCheckOutTable.php', 5000);
|
||||||
|
initOne('#checkin-scroll', '#checkin-table', '#getCheckInTableHolder', 'sources/getCheckInTable.php', 5000);
|
||||||
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
/* Scroll-Wrapper je Tabelle */
|
||||||
|
.tableFixHead {
|
||||||
|
overflow-y: auto;
|
||||||
|
/* Höhe wird per JS dynamisch gesetzt, damit genau bis zum Viewport-Ende gescrollt wird */
|
||||||
|
max-height: 60vh; /* Fallback */
|
||||||
|
border: 1px solid rgba(255,255,255,.1);
|
||||||
|
border-radius: .25rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Sticky Header */
|
||||||
|
.tableFixHead thead th {
|
||||||
|
position: sticky;
|
||||||
|
top: 0;
|
||||||
|
z-index: 2; /* über Body-Zellen */
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Saubere Hintergrundfarbe für sticky Header (Bootstrap .table-dark) */
|
||||||
|
.table-dark thead th {
|
||||||
|
background-color: #212529; /* gleiche Farbe wie .table-dark header */
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Optional: dünne Trennlinien */
|
||||||
|
.table-dark tbody tr + tr td {
|
||||||
|
border-top: 1px solid rgba(255,255,255,.08);
|
||||||
|
}
|
||||||
|
|
||||||
|
body { background-color: black; margin-bottom: 0; }
|
||||||
|
</style>
|
||||||
</head>
|
</head>
|
||||||
<body style="background-color: black;">
|
<body>
|
||||||
|
|
||||||
<div class="container-fluid">
|
<div class="container-fluid">
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col-lg">
|
<!-- Check-Out -->
|
||||||
<h2 class="text-light">Check-Out
|
<div class="col-sm">
|
||||||
<?php
|
<h2 class="text-light">Check-Out</h2>
|
||||||
if (CheckOut_FutureDays != -1) {
|
<div class="tableFixHead" id="checkout-scroll">
|
||||||
echo "in den nächsten " . CheckOut_FutureDays . " Tagen";
|
<table class="table table-dark mb-0" id="checkout-table">
|
||||||
}
|
|
||||||
?></h2>
|
|
||||||
<table class="table table-dark">
|
|
||||||
<thead>
|
<thead>
|
||||||
<tr>
|
<tr>
|
||||||
<th scope="col">#</th>
|
<th scope="col">#</th>
|
||||||
<th scope="col">Kunde</th>
|
<th scope="col">Kunde</th>
|
||||||
<th scope="col">Event</th>
|
<th scope="col">Event</th>
|
||||||
<th scope="col">Dispo-Start<br><i>VB-Start</i></th>
|
|
||||||
<?php
|
<?php
|
||||||
|
if(ShowCheckoutTimeOnCheckout || ShowVorbereitungTimeOnCheckout||ShowPackagingTimeOnCheckout || ShowDeliveryTimeOnCheckout){
|
||||||
if(!HideCheckInTimeOnCheckout){
|
echo '<th scope="col">';
|
||||||
echo "<th scope='col'>Dispo-Ende<br><i>VB-Ende</i></th>";
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(ShowCheckoutTimeOnCheckout){
|
||||||
|
echo "Dispo-Start";
|
||||||
|
}
|
||||||
|
if(ShowVorbereitungTimeOnCheckout){
|
||||||
|
if(ShowCheckoutTimeOnCheckout){echo "<br>";}
|
||||||
|
echo "VB-Start";
|
||||||
|
}
|
||||||
|
if(ShowPackagingTimeOnCheckout){
|
||||||
|
if(ShowCheckoutTimeOnCheckout||ShowVorbereitungTimeOnCheckout){echo "<br>";}
|
||||||
|
echo "Packen";
|
||||||
|
}
|
||||||
|
if(ShowDeliveryTimeOnCheckout){
|
||||||
|
if(ShowCheckoutTimeOnCheckout || ShowVorbereitungTimeOnCheckout||ShowPackagingTimeOnCheckout){echo "<br>";}
|
||||||
|
echo "Liefern";
|
||||||
|
}
|
||||||
|
if(ShowCheckoutTimeOnCheckout || ShowVorbereitungTimeOnCheckout||ShowPackagingTimeOnCheckout || ShowDeliveryTimeOnCheckout){
|
||||||
|
echo '</th>';
|
||||||
|
}
|
||||||
|
|
||||||
?>
|
?>
|
||||||
<th scope="col">Status</th>
|
<th scope="col">Status</th>
|
||||||
|
<?php
|
||||||
|
if(ShowShippingIcons){
|
||||||
|
echo "<th scope='col'>Shipping</th>";
|
||||||
|
}
|
||||||
|
?>
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody id="getCheckOutTableHolder">
|
<tbody id="getCheckOutTableHolder"></tbody>
|
||||||
|
|
||||||
</tbody>
|
|
||||||
</table>
|
</table>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
<div class="col-lg">
|
</div>
|
||||||
<h2 class="text-light">Check-In
|
|
||||||
<?php
|
<!-- Check-In -->
|
||||||
if (CheckIn_FutureDays != -1) {
|
<div class="col-sm">
|
||||||
echo "in den nächsten " . CheckIn_FutureDays . " Tagen";
|
<h2 class="text-light">Check-In</h2>
|
||||||
}
|
<div class="tableFixHead" id="checkin-scroll">
|
||||||
?></h2>
|
<table class="table table-dark mb-0" id="checkin-table">
|
||||||
<table class="table table-dark">
|
|
||||||
<thead>
|
<thead>
|
||||||
<tr>
|
<tr>
|
||||||
<th scope="col">#</th>
|
<th scope="col">#</th>
|
||||||
<th scope="col">Kunde</th>
|
<th scope="col">Kunde</th>
|
||||||
<th scope="col">Event</th>
|
<th scope="col">Event</th>
|
||||||
|
|
||||||
<?php
|
<?php
|
||||||
|
if(ShowCheckInTimeOnCheckin || ShowNachbereitungTimeOnCheckin ||ShowRePackagingTimeOnCheckin || ShowReDeliveryTimeOnCheckin){
|
||||||
|
echo '<th scope="col">';
|
||||||
|
}
|
||||||
|
|
||||||
if(!HideCheckOutTimeOnCheckin){
|
if(ShowCheckInTimeOnCheckin){
|
||||||
echo "<th scope='col'>Dispo-Start<br><i>RP-Start</i></th>";
|
echo "Dispo-Ende";
|
||||||
|
}
|
||||||
|
if(ShowNachbereitungTimeOnCheckin){
|
||||||
|
if(ShowCheckInTimeOnCheckin){echo "<br>";}
|
||||||
|
echo "Nachbereitung";
|
||||||
|
}
|
||||||
|
if(ShowRePackagingTimeOnCheckin){
|
||||||
|
if(ShowCheckInTimeOnCheckin||ShowNachbereitungTimeOnCheckin){echo "<br>";}
|
||||||
|
echo "Zurückpacken";
|
||||||
|
}
|
||||||
|
if(ShowReDeliveryTimeOnCheckin){
|
||||||
|
if(ShowCheckInTimeOnCheckin || ShowNachbereitungTimeOnCheckin||ShowRePackagingTimeOnCheckin){echo "<br>";}
|
||||||
|
echo "Rückliefern";
|
||||||
|
}
|
||||||
|
if(ShowCheckInTimeOnCheckin || ShowNachbereitungTimeOnCheckin||ShowRePackagingTimeOnCheckin || ShowReDeliveryTimeOnCheckin){
|
||||||
|
echo '</th>';
|
||||||
|
}
|
||||||
|
|
||||||
|
?>
|
||||||
|
<th scope="col">Status</th>
|
||||||
|
<?php
|
||||||
|
if(ShowShippingIcons){
|
||||||
|
echo "<th scope='col'>Shipping</th>";
|
||||||
}
|
}
|
||||||
?>
|
?>
|
||||||
<th scope="col">Dispo-Ende<br><i>RP-Ende</i></th>
|
|
||||||
<th scope="col">Status</th>
|
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody id="getCheckInTableHolder">
|
<tbody id="getCheckInTableHolder"></tbody>
|
||||||
|
|
||||||
</tbody>
|
|
||||||
</table>
|
</table>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
</header>
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<script src="vendor/twbs/bootstrap/dist/js/bootstrap.min.js" crossorigin="anonymous"></script>
|
||||||
|
|
||||||
<!-- jQuery (necessary for Bootstrap's JavaScript plugins) -->
|
|
||||||
<script src="https://code.jquery.com/jquery-1.12.4.min.js" integrity="sha384-nvAa0+6Qg9clwYCGGPpDQLVpLNn0fRaROjHqs13t4Ggj3Ez50XnGQqc/r8MhnRDZ" crossorigin="anonymous"></script>
|
|
||||||
<!-- Include all compiled plugins (below), or include individual files as needed -->
|
|
||||||
<script src="vendor/twbs/bootstrap/dist/js/bootstrap.min.js" integrity="sha384-aJ21OjlMXNL5UyIl/XNwTMqvzeRMZH2w8c5cRVpzpU8Y5bApTppSuUkhZXN0VxHd" crossorigin="anonymous"></script>
|
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|
||||||
|
|
||||||
<?php
|
<?php
|
||||||
|
|
||||||
function getTimeFromSeconds(string $timestring) {
|
function getTimeFromSeconds(string $timestring) {
|
||||||
|
|
||||||
$hours = floor($timestring / 3600);
|
$hours = floor($timestring / 3600);
|
||||||
$mins = floor($timestring / 60 % 60);
|
$mins = floor($timestring / 60 % 60);
|
||||||
$secs = floor($timestring % 60);
|
return sprintf('%02d:%02d', $hours, $mins);
|
||||||
|
|
||||||
$timeFormat = sprintf('%02d:%02d', $hours, $mins);
|
|
||||||
|
|
||||||
return $timeFormat;
|
|
||||||
}
|
}
|
||||||
?>
|
?>
|
||||||
13
README.MD
13
README.MD
@@ -1,8 +1,8 @@
|
|||||||
# EPIWebview
|
# EPIWebview
|
||||||
|
|
||||||
**aktuellste stable Version:** 1.5.0
|
- **aktuellste stable Version:** 1.5.0
|
||||||
**Lizenz:** Creative Commons Attribution-NonCommercial-ShareAlike 4.0 (CC BY-NC-SA 4.0). Einsehbar unter: (LICENSE.MD)
|
- **Lizenz:** Creative Commons Attribution-NonCommercial-ShareAlike 4.0 (CC BY-NC-SA 4.0). Einsehbar unter: (LICENSE.MD)
|
||||||
**Kompatibilität:** Erweiterung für **Epirent** und **CrewBrain**
|
- **Kompatibilität:** Erweiterung für **Epirent** und **CrewBrain**
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
@@ -38,10 +38,5 @@ Die Anwendung ist speziell für den Einsatz in Lagerprozessen entwickelt.
|
|||||||
git clone http://srvgitea01.vtm.zone:3000/epi/EpiWebview
|
git clone http://srvgitea01.vtm.zone:3000/epi/EpiWebview
|
||||||
|
|
||||||
## Changelog
|
## Changelog
|
||||||
### Änderungen in Version 1.5.0
|
Verschoben in Releases (Git)
|
||||||
|
|
||||||
**Neu:**
|
|
||||||
- Die Spalte **„CheckIn“** kann beim **Checkout** ausgeblendet werden.
|
|
||||||
- Die Spalte **„CheckOut“** kann beim **Checkin** ausgeblendet werden.
|
|
||||||
|
|
||||||
---
|
---
|
||||||
7
dist/index.php
vendored
7
dist/index.php
vendored
@@ -11,6 +11,13 @@
|
|||||||
<link href="https://cdn.datatables.net/1.10.20/css/dataTables.bootstrap4.min.css" rel="stylesheet" crossorigin="anonymous" />
|
<link href="https://cdn.datatables.net/1.10.20/css/dataTables.bootstrap4.min.css" rel="stylesheet" crossorigin="anonymous" />
|
||||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.15.1/js/all.min.js" crossorigin="anonymous"></script>
|
<script src="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.15.1/js/all.min.js" crossorigin="anonymous"></script>
|
||||||
<script src="js/jquery-3.5.1.min.js"></script>
|
<script src="js/jquery-3.5.1.min.js"></script>
|
||||||
|
<script src="https://kit.fontawesome.com/93d71de8bc.js" crossorigin="anonymous"></script>
|
||||||
|
|
||||||
|
<link href="/src/fa/css/fontawesome.css" rel="stylesheet" />
|
||||||
|
<link href="/src/fa/css/brands.css" rel="stylesheet" />
|
||||||
|
<link href="/src/fa/css/solid.css" rel="stylesheet" />
|
||||||
|
<link href="/src/fa/css/sharp-thin.css" rel="stylesheet" />
|
||||||
|
<link href="/src/fa/css/sharp-duotone-thin.css" rel="stylesheet" />
|
||||||
<script type="text/javascript">
|
<script type="text/javascript">
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -20,16 +20,53 @@ define('Enable_QR_Code_CrewBrainAufgaben', true);
|
|||||||
define('Enable_QR_Code_CheckOut', false); //Zeigt statt der Packscheinnummer einen Scanbaren QR Code für den CheckOut an
|
define('Enable_QR_Code_CheckOut', false); //Zeigt statt der Packscheinnummer einen Scanbaren QR Code für den CheckOut an
|
||||||
define('Enable_QR_Code_CheckIn', false); //Zeigt statt der Packscheinnummer einen Scanbaren QR Code für den CheckIn an
|
define('Enable_QR_Code_CheckIn', false); //Zeigt statt der Packscheinnummer einen Scanbaren QR Code für den CheckIn an
|
||||||
define('Vorbereitungs_Zeitvariable', 'Packen'); //Name des zu verwendenden Zeitabschnitts, der Zusätzlich zur DispoZeit beim Check Out Angezeigt werden soll
|
define('Vorbereitungs_Zeitvariable', 'Packen'); //Name des zu verwendenden Zeitabschnitts, der Zusätzlich zur DispoZeit beim Check Out Angezeigt werden soll
|
||||||
define('Rueckpacken_Zeitvariable', 'Rückpacken'); //Name des zu verwendenden Zeitabschnitts, der Zusätzlich zur DispoZeit beim Check In Angezeigt werden soll
|
define('Nachbereitung_Zeitvariable', 'Rückpacken'); //Name des zu verwendenden Zeitabschnitts, der Zusätzlich zur DispoZeit beim Check In Angezeigt werden soll
|
||||||
|
define('Rückpacken_Zeitvariable', 'Rückpacken');
|
||||||
|
|
||||||
define('UsePackingNoteDateForCheckout', true); // Nutzt statt den Zeitabscnitten aus dem Auftrag die Informationen aus dem Packschein für den Checkout. Wenn die UseDispo Variablen false sind, werden diese Variablen für das Rowmarking genutzt falls "true".
|
/** -------------------- Row-Marking: Konfig Zusände --------------------
|
||||||
define('UsePackingNoteDateForCheckin', true); // Nutzt statt den Zeitabscnitten aus dem Auftrag die Informationen aus dem Packschein für den Checkout. Wenn die UseDispo Variablen false sind, werden diese Variablen für das Rowmarking genutzt falls "true".
|
* 1 = $packingjob->date_start (Dispo Start)
|
||||||
|
* 2 = $VorbereitungsTimeDetail->date_start (Vorbereitung Start)
|
||||||
|
* 3 = $PackingNoteDetail->date_packing (Packen Zeit)
|
||||||
|
* 4 = $PackingNoteDetail->date_delivery (Delivery Zeit)
|
||||||
|
*/
|
||||||
|
define('CheckOutRowMarkSource', 4);
|
||||||
|
|
||||||
|
/** -------------------- Row-Marking: Konfig Zusände --------------------
|
||||||
|
* 1 = $packingjob->date_end (Dispo Ende)
|
||||||
|
* 2 = $NachbereitungssTimeDetail->date_start (Nachbereitung Start)
|
||||||
|
* 3 = $RePackagingTimeDetail->date_start (Rückpacken Zeit AUS AUFTRAG)
|
||||||
|
* 4 = $PackingNoteDetail->date_redelivery (ReDelivery Zeit)
|
||||||
|
*/
|
||||||
|
define('CheckInRowMarkSource', 4);
|
||||||
|
|
||||||
define('CheckOut_UseDispoStartForRowMarking', false); //else: Use Same Variable as "Vorbereitung Zeitvariable" | Konfiguration, welche Zeit für die Zeilenmarkierung beim CheckOut Verwendet werden soll
|
|
||||||
define('CheckIn_UseDispoEndForRowMarking', false); //else: Use Same Variable as "Rueckpacken Zeitvariable" | Konfiguration, welche Zeit für die Zeilenmarkierung beim Check In Verwendet werden soll
|
define('CheckIn_UseDispoEndForRowMarking', false); //else: Use Same Variable as "Rueckpacken Zeitvariable" | Konfiguration, welche Zeit für die Zeilenmarkierung beim Check In Verwendet werden soll
|
||||||
|
|
||||||
define('HideCheckInTimeOnCheckout', true); //Versteckt die CheckIn Zeit im Checkout
|
define('ShowCheckoutTimeOnCheckout', true);
|
||||||
define('HideCheckOutTimeOnCheckin', true); //Versteckt die CheckOut Zeit im CheckIn
|
define('ShowVorbereitungTimeOnCheckout', true);
|
||||||
|
define('ShowPackagingTimeOnCheckout', true);
|
||||||
|
define('ShowDeliveryTimeOnCheckout', true);
|
||||||
|
define('ShowTimesOnCheckout', true);
|
||||||
|
|
||||||
|
define('ShowCheckInTimeOnCheckin', true);
|
||||||
|
define('ShowNachbereitungTimeOnCheckin', true);
|
||||||
|
define('ShowRePackagingTimeOnCheckin', true);
|
||||||
|
define('ShowReDeliveryTimeOnCheckin', true);
|
||||||
|
define('ShowTimesOnCheckin', true);
|
||||||
|
|
||||||
|
define('ShowShippingIcons', true); //Zeigt Lieferung / Rücklieferungs Icons an
|
||||||
|
define('KurierContainsText', 'Kurier'); //Text, der in der Versandart enthalten sein muss (enthält), damit diese als KURIER erkannt wird.
|
||||||
|
define('SpeditionContainsText', 'Spedition'); //Text, der in der Versandart enthalten sein muss (enthält), damit diese als SPEDITION erkannt wird.
|
||||||
|
define('DHLContainsText', 'DHL'); //Text, der in der Versandart enthalten sein muss (enthält), damit diese als DHL erkannt wird.
|
||||||
|
define('LKWContainsText', 'LKW'); //Text, der in der Versandart enthalten sein muss (enthält), damit diese als eigener LKW erkannt wird.
|
||||||
|
define('TransporterContainsText', 'Sprinter'); //Text, der in der Versandart enthalten sein muss (enthält), damit diese als eigener Transporter erkannt wird.
|
||||||
|
define('PKWContainsText', 'PKW'); //Text, der in der Versandart enthalten sein muss (enthält), damit diese als eigener PKW erkannt wird.
|
||||||
|
|
||||||
|
define('UseShippingStatus', true); //Nutzt den Packscheinstatus als Shipping Status. Hierdurch können die Icons unter verschiedenen Vorraussetzungen Grün werden, wenn der Versand organisiert wurde
|
||||||
|
define('ShippingOutOrganizedStatus', 'Hinversand OK'); //Packschein Status (EpirentDropdown) der Gematcht werden muss, dass der Hinversand Organisiert / Bestellt wurde
|
||||||
|
define('ShippingInOrganizedStatus', 'Rückversand OK'); //Packschein Status (EpirentDropdown) der Gematcht werden muss, dass der Rückversand Organisiert / Bestellt wurde
|
||||||
|
define('ShippingOrganizedStatus', 'Versand OK'); //Packschein Status (EpirentDropdown) der Gematcht werden muss, dass der komplette Versand Organisiert / Bestellt wurde
|
||||||
|
|
||||||
|
define('UseDeliveredForCheckOutCompleted', true); //Nutzt statt dem erfolgreichen abschließen eines Packscheins durch ausbuchen das erfolgreiche Liefern (Geliefert != 00.00.00)
|
||||||
|
|
||||||
define('CheckOut_FutureDays', -1); // Konfiguration, wie viele Tage in der Zukunft der CheckOut angezeigt werden soll. '-1' zeigt alle an. Abhängig von der Variablen CheckOut_UseDispoStartForRowMarking
|
define('CheckOut_FutureDays', -1); // Konfiguration, wie viele Tage in der Zukunft der CheckOut angezeigt werden soll. '-1' zeigt alle an. Abhängig von der Variablen CheckOut_UseDispoStartForRowMarking
|
||||||
define('CheckIn_FutureDays', -1); // Konfiguration, wie viele Tage in der Zukunft der CheckIn angezeigt werden soll. '-1' zeigt alle an. Abhängig von der Variablen CheckIn_UseDispoEndForRowMarking
|
define('CheckIn_FutureDays', -1); // Konfiguration, wie viele Tage in der Zukunft der CheckIn angezeigt werden soll. '-1' zeigt alle an. Abhängig von der Variablen CheckIn_UseDispoEndForRowMarking
|
||||||
|
|||||||
@@ -62,9 +62,13 @@ foreach ($data_output as $aufgabe) {
|
|||||||
}
|
}
|
||||||
echo "<td>";
|
echo "<td>";
|
||||||
|
|
||||||
|
$i=0;
|
||||||
foreach($AufgabeDetail->Responsibles as $bearbeiter){
|
foreach($AufgabeDetail->Responsibles as $bearbeiter){
|
||||||
echo $bearbeiter->Name;
|
echo $bearbeiter->Name;
|
||||||
|
if($i>0){
|
||||||
|
echo ", ";
|
||||||
|
}
|
||||||
|
$i++;
|
||||||
}
|
}
|
||||||
echo "</td>";
|
echo "</td>";
|
||||||
echo "<td>" . $aufgabe->Titel . "</td>";
|
echo "<td>" . $aufgabe->Titel . "</td>";
|
||||||
|
|||||||
@@ -10,8 +10,6 @@ use chillerlan\QRCode\{
|
|||||||
|
|
||||||
require('../vendor/autoload.php');
|
require('../vendor/autoload.php');
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
$options = new QROptions([
|
$options = new QROptions([
|
||||||
'imageBase64' => false,
|
'imageBase64' => false,
|
||||||
'qrCodeHeight' => 75,
|
'qrCodeHeight' => 75,
|
||||||
@@ -20,123 +18,232 @@ $options = new QROptions([
|
|||||||
'quietzoneSize' => 1
|
'quietzoneSize' => 1
|
||||||
]);
|
]);
|
||||||
|
|
||||||
|
|
||||||
$Epi = new Epirent();
|
$Epi = new Epirent();
|
||||||
|
|
||||||
|
|
||||||
$result = $Epi->requestEpiApi('/v1/packingnote/open?isco=False&cl=' . Epirent_Mandant);
|
$result = $Epi->requestEpiApi('/v1/packingnote/open?isco=False&cl=' . Epirent_Mandant);
|
||||||
|
|
||||||
$data_output = json_decode($result)->payload;
|
$data_output = json_decode($result)->payload;
|
||||||
|
|
||||||
|
/** ---------- Helpers & Marking (analog Checkout) ---------- */
|
||||||
|
const APP_TZ = 'Europe/Berlin';
|
||||||
|
|
||||||
|
function dt(?string $s): ?DateTimeImmutable {
|
||||||
|
if (!$s) return null;
|
||||||
|
try {
|
||||||
|
return new DateTimeImmutable($s, new DateTimeZone(APP_TZ));
|
||||||
|
} catch (Throwable $e) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function dayStart(DateTimeImmutable $d): DateTimeImmutable {
|
||||||
|
return $d->setTime(0, 0, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
function rowClassForDate(?DateTimeImmutable $markDate, ?DateTimeImmutable $today): string {
|
||||||
|
if (!$markDate || !$today) return '';
|
||||||
|
if ($markDate == $today) return 'text-dark bg-warning';
|
||||||
|
if ($markDate < $today) return 'bg-danger';
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Row-Marking Quelle (Check-In):
|
||||||
|
* 1 = $packingjob->date_end
|
||||||
|
* 2 = $NachbereitungsTimeDetail->date_start
|
||||||
|
* 3 = $RePackagingTimeDetail->date_start
|
||||||
|
* 4 = $PackingNoteDetail->date_redelivery
|
||||||
|
* Fallback: $packingjob->date_end
|
||||||
|
*/
|
||||||
|
function resolveRowMarkDateCheckIn(
|
||||||
|
$packingjob,
|
||||||
|
$NachbereitungsTimeDetail,
|
||||||
|
$RePackagingTimeDetail,
|
||||||
|
$PackingNoteDetail,
|
||||||
|
int $source
|
||||||
|
): ?DateTimeImmutable {
|
||||||
|
$candidate = null;
|
||||||
|
switch ($source) {
|
||||||
|
case 1: $candidate = dt($packingjob->date_end ?? null); break;
|
||||||
|
case 2: $candidate = dt($NachbereitungsTimeDetail->date_start ?? null); break;
|
||||||
|
case 3: $candidate = dt($RePackagingTimeDetail->date_start ?? null); break;
|
||||||
|
case 4: $candidate = dt($PackingNoteDetail->date_redelivery ?? null); break;
|
||||||
|
default: $candidate = null; break;
|
||||||
|
}
|
||||||
|
if (!$candidate) {
|
||||||
|
$candidate = dt($packingjob->date_end ?? null);
|
||||||
|
}
|
||||||
|
return $candidate ? dayStart($candidate) : null;
|
||||||
|
}
|
||||||
|
|
||||||
|
function echoMarkedTimeLine(?string $dateStr, ?int $timeSeconds, DateTimeImmutable $today, $ReturnTime): void {
|
||||||
|
if (!$dateStr) return;
|
||||||
|
$d = dt($dateStr);
|
||||||
|
if (!$d) return;
|
||||||
|
|
||||||
|
$mark = dayStart($d);
|
||||||
|
$cls = rowClassForDate($mark, $today);
|
||||||
|
|
||||||
|
echo $cls ? "<span class=\"{$cls}\">" : "";
|
||||||
|
echo date_format(new \DateTime($dateStr), 'd.m.Y');
|
||||||
|
if ($ReturnTime) {
|
||||||
|
echo " " . getTimeFromSeconds((string)$timeSeconds);
|
||||||
|
}
|
||||||
|
echo $cls ? "</span>" : "";
|
||||||
|
}
|
||||||
|
|
||||||
|
/** ---------- Sortierung nach Ende ---------- */
|
||||||
if (SortCheckIn == 2) {
|
if (SortCheckIn == 2) {
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// Prüfen, ob $data_output ein Array ist
|
|
||||||
if (is_array($data_output)) {
|
if (is_array($data_output)) {
|
||||||
usort($data_output, function ($a, $b) {
|
usort($data_output, function ($a, $b) {
|
||||||
// Konvertiere time_start von Millisekunden in Sekunden
|
$timeEndA = $a->time_end / 1000;
|
||||||
$timeStartA = $a->time_end / 1000; // Zeit in Sekunden
|
$timeEndB = $b->time_end / 1000;
|
||||||
$timeStartB = $b->time_end / 1000;
|
$datetimeA = strtotime($a->date_end) + $timeEndA;
|
||||||
|
$datetimeB = strtotime($b->date_end) + $timeEndB;
|
||||||
// Kombiniere date_start mit time_start
|
|
||||||
$datetimeA = strtotime($a->date_end) + $timeStartA;
|
|
||||||
$datetimeB = strtotime($b->date_end) + $timeStartB;
|
|
||||||
|
|
||||||
// Vergleich für die Sortierung
|
|
||||||
return $datetimeA <=> $datetimeB;
|
return $datetimeA <=> $datetimeB;
|
||||||
});
|
});
|
||||||
|
|
||||||
// Sortierte Daten ausgeben oder weiterverarbeiten
|
|
||||||
// print_r($data_output);
|
|
||||||
} else {
|
} else {
|
||||||
echo "Daten konnten nicht verarbeitet werden.";
|
echo "Daten konnten nicht verarbeitet werden.";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** ---------- Tabelle ---------- */
|
||||||
|
|
||||||
foreach ($data_output as $packingjob) {
|
foreach ($data_output as $packingjob) {
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
if ($packingjob->is_archived != true) {
|
if ($packingjob->is_archived != true) {
|
||||||
|
|
||||||
//get OrderDetails
|
// OrderDetails
|
||||||
$result = $Epi->requestEpiApi('/v1/order/' . $packingjob->order_pk . '?cl=' . Epirent_Mandant);
|
$result = $Epi->requestEpiApi('/v1/order/' . $packingjob->order_pk . '?cl=' . Epirent_Mandant);
|
||||||
|
|
||||||
$orderdetail_output = json_decode($result)->payload[0];
|
$orderdetail_output = json_decode($result)->payload[0];
|
||||||
|
|
||||||
$NachbereitungsTimeDetail;
|
// PackingNote Details
|
||||||
|
$PackingNoteDetailResult = $Epi->requestEpiApi('/v1/packingnote/' . $packingjob->primary_key . '?cl=' . Epirent_Mandant);
|
||||||
|
$PackingNoteDetail = json_decode($PackingNoteDetailResult)->payload[0];
|
||||||
|
|
||||||
|
// Zeit-Slots aus dem Schedule
|
||||||
|
$NachbereitungsTimeDetail = null;
|
||||||
|
$RePackagingTimeDetail = null;
|
||||||
|
|
||||||
foreach ($orderdetail_output->order_schedule as $scheduledetail) {
|
foreach ($orderdetail_output->order_schedule as $scheduledetail) {
|
||||||
|
if ($scheduledetail->name == Nachbereitung_Zeitvariable) {
|
||||||
if ($scheduledetail->name == Rueckpacken_Zeitvariable) {
|
|
||||||
$NachbereitungsTimeDetail = $scheduledetail;
|
$NachbereitungsTimeDetail = $scheduledetail;
|
||||||
}
|
}
|
||||||
|
if ($scheduledetail->name == Rückpacken_Zeitvariable) {
|
||||||
|
$RePackagingTimeDetail = $scheduledetail;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// --- Row-Marking bestimmen (konfigurierbar, analog Checkout) ---
|
||||||
//End Of get Order Details
|
$today = dayStart(new DateTimeImmutable('today', new DateTimeZone(APP_TZ)));
|
||||||
|
$limit = null;
|
||||||
|
if (CheckIn_FutureDays != -1) {
|
||||||
|
$limit = $today->modify('+' . (int)CheckIn_FutureDays . ' day');
|
||||||
if (CheckIn_UseDispoEndForRowMarking || ($NachbereitungsTimeDetail->date_start == null)) {
|
|
||||||
$date = new DateTime($packingjob->date_end);
|
|
||||||
} else {
|
|
||||||
$date = new DateTime($NachbereitungsTimeDetail->date_start);
|
|
||||||
}
|
}
|
||||||
$date->setTime(0, 0, 0);
|
|
||||||
$today = new DateTime();
|
|
||||||
$today->setTime(0, 0, 0);
|
|
||||||
$todayFilter = new DateTime();
|
|
||||||
$todayFilter->setTime(0, 0, 0);
|
|
||||||
if (CheckIn_FutureDays == -1 || $date <= ($todayFilter->modify('+' . CheckIn_FutureDays . ' day'))) {
|
|
||||||
//prüfe, ob entweder unbegrenzte (-1) Anzeige Aktiv ist, oder das Datum kleiner oder Gleich heute + Zukunftsspanne ist
|
|
||||||
|
|
||||||
if ($date == $today) {
|
// Override-Flag wie bei Checkout: Dispo-Ende erzwingen
|
||||||
|
$source = CheckIn_UseDispoEndForRowMarking ? 1 : (int)CheckInRowMarkSource;
|
||||||
|
|
||||||
echo "<tr class='text-dark bg-warning'>";
|
$markDate = resolveRowMarkDateCheckIn(
|
||||||
} else if ($date < $today) {
|
$packingjob,
|
||||||
echo "<tr class=' bg-danger'>";
|
$NachbereitungsTimeDetail,
|
||||||
} else {
|
$RePackagingTimeDetail,
|
||||||
echo "<tr>";
|
$PackingNoteDetail,
|
||||||
}
|
$source
|
||||||
|
);
|
||||||
|
|
||||||
|
if (CheckIn_FutureDays == -1 || ($markDate && (!$limit || $markDate <= $limit))) {
|
||||||
|
$trClass = rowClassForDate($markDate, $today);
|
||||||
|
echo $trClass ? "<tr class='{$trClass}'>" : "<tr>";
|
||||||
|
|
||||||
|
// QR / Kopfspalten
|
||||||
if (Enable_QR_Code_CheckIn) {
|
if (Enable_QR_Code_CheckIn) {
|
||||||
echo "<td>" . '<div style="width: 5vb;">' . (new QRCode($options))->render($packingjob->packingnote_no) . "</div></td>";
|
echo "<td><div style=\"width: 5vb;\">" . (new QRCode($options))->render($packingjob->packingnote_no) . "</div></td>";
|
||||||
} else {
|
} else {
|
||||||
echo "<td>" . $packingjob->packingnote_no . "</td>";
|
echo "<td>" . $packingjob->packingnote_no . "</td>";
|
||||||
}
|
}
|
||||||
echo "<td>" . $packingjob->contact->name . "</td>";
|
echo "<td>" . $packingjob->contact->name . "</td>";
|
||||||
echo "<td>" . $packingjob->event . "</td>";
|
echo "<td>" . $packingjob->event . "</td>";
|
||||||
if(!HideCheckOutTimeOnCheckin){
|
|
||||||
if ($NachbereitungsTimeDetail->date_start != null) {
|
// Zeitspalte öffnen, wenn mindestens eine Anzeige aktiv ist
|
||||||
echo "<td><small>" . date_format(new \DateTime($packingjob->date_start), 'd.m.Y') . " " . getTimeFromSeconds($packingjob->time_start) . "</small><br><i>" . date_format(new \DateTime($NachbereitungsTimeDetail->date_start), 'd.m.Y') . " " . getTimeFromSeconds($NachbereitungsTimeDetail->time_start) . "</i></td>";
|
if (ShowCheckInTimeOnCheckin || ShowNachbereitungTimeOnCheckin || ShowRePackagingTimeOnCheckin || ShowReDeliveryTimeOnCheckin) {
|
||||||
} else {
|
|
||||||
echo "<td>" . date_format(new \DateTime($packingjob->date_start), 'd.m.Y') . " " . getTimeFromSeconds($packingjob->time_start) . "</td>";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if ($NachbereitungsTimeDetail->date_end != null) {
|
|
||||||
echo "<td><small>" . date_format(new \DateTime($packingjob->date_end), 'd.m.Y') . " " . getTimeFromSeconds($packingjob->time_end) . "</small><br><i>" . date_format(new \DateTime($NachbereitungsTimeDetail->date_end), 'd.m.Y') . " " . getTimeFromSeconds($NachbereitungsTimeDetail->time_end) . "</i></td>";
|
|
||||||
} else {
|
|
||||||
echo "<td>" . date_format(new \DateTime($packingjob->date_end), 'd.m.Y') . " " . getTimeFromSeconds($packingjob->time_end) . "</td>";
|
|
||||||
}
|
|
||||||
echo "<td>";
|
echo "<td>";
|
||||||
|
}
|
||||||
|
|
||||||
|
// Dispo-Ende (Check-In Termin) — ENDE korrekt verwendet
|
||||||
|
if (ShowCheckInTimeOnCheckin && $packingjob->date_end != null) {
|
||||||
|
echoMarkedTimeLine($packingjob->date_end, (int)$packingjob->time_end, $today, ShowTimesOnCheckin);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Nachbereitung (START) — wie von dir bereits genutzt
|
||||||
|
if (ShowNachbereitungTimeOnCheckin && $NachbereitungsTimeDetail && $NachbereitungsTimeDetail->date_start != null) {
|
||||||
|
if (ShowCheckInTimeOnCheckin) echo "<br>";
|
||||||
|
echoMarkedTimeLine($NachbereitungsTimeDetail->date_start, (int)$NachbereitungsTimeDetail->time_start, $today, ShowTimesOnCheckin);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Rückpacken (START)
|
||||||
|
if (ShowRePackagingTimeOnCheckin && $RePackagingTimeDetail && $RePackagingTimeDetail->date_start != null) {
|
||||||
|
if (ShowCheckInTimeOnCheckin || ShowNachbereitungTimeOnCheckin) echo "<br>";
|
||||||
|
echoMarkedTimeLine($RePackagingTimeDetail->date_start, (int)$RePackagingTimeDetail->time_start, $today, ShowTimesOnCheckin);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Rücklieferung (REDELIVERY) — delivery ↔ redelivery gespiegelt
|
||||||
|
if (ShowReDeliveryTimeOnCheckin && $PackingNoteDetail && $PackingNoteDetail->date_redelivery != null) {
|
||||||
|
if (ShowCheckInTimeOnCheckin || ShowNachbereitungTimeOnCheckin || ShowRePackagingTimeOnCheckin) echo "<br>";
|
||||||
|
echoMarkedTimeLine($PackingNoteDetail->date_redelivery, (int)$PackingNoteDetail->time_redelivery, $today, ShowTimesOnCheckin);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ShowCheckInTimeOnCheckin || ShowNachbereitungTimeOnCheckin || ShowRePackagingTimeOnCheckin || ShowReDeliveryTimeOnCheckin) {
|
||||||
|
echo "</td>";
|
||||||
|
}
|
||||||
|
|
||||||
|
// Fortschritt
|
||||||
|
echo "<td>";
|
||||||
if ($packingjob->is_all_in == 0) {
|
if ($packingjob->is_all_in == 0) {
|
||||||
echo "<span class='badge badge-success'>";
|
echo "<span class='badge badge-success'>";
|
||||||
} else {
|
} else {
|
||||||
|
echo '<div class="progress"><div class="progress-bar progress-bar-striped progress-bar-animated" role="progressbar" style="width: ' .
|
||||||
echo '<div class="progress"><div class="progress-bar progress-bar-striped progress-bar-animated" role="progressbar" style="width: '.(( $packingjob->pieces_sum_total - abs($packingjob->is_all_out) - abs($packingjob->is_all_in)) / ($packingjob->pieces_sum_total - $packingjob ->is_all_out)) *100 .'%" aria-valuenow="' .( $packingjob->pieces_sum_total - abs($packingjob->is_all_out) - abs($packingjob->is_all_in)) . '" aria-valuemin="0" aria-valuemax="' . ($packingjob->pieces_sum_total - $packingjob ->is_all_out). '"></div></div>';
|
(( $packingjob->pieces_sum_total - abs($packingjob->is_all_out) - abs($packingjob->is_all_in)) / ($packingjob->pieces_sum_total - $packingjob->is_all_out)) * 100 .
|
||||||
|
'%" aria-valuenow="' . ( $packingjob->pieces_sum_total - abs($packingjob->is_all_out) - abs($packingjob->is_all_in)) .
|
||||||
|
'" aria-valuemin="0" aria-valuemax="' . ($packingjob->pieces_sum_total - $packingjob->is_all_out) . '"></div></div>';
|
||||||
echo "<span class='badge badge-info'>";
|
echo "<span class='badge badge-info'>";
|
||||||
}
|
}
|
||||||
|
|
||||||
echo ( $packingjob->pieces_sum_total - abs($packingjob->is_all_out) - abs($packingjob->is_all_in)) . "/" . ($packingjob->pieces_sum_total - $packingjob->is_all_out) . " (" . $packingjob->pieces_sum_total . ")";
|
echo ( $packingjob->pieces_sum_total - abs($packingjob->is_all_out) - abs($packingjob->is_all_in)) . "/" . ($packingjob->pieces_sum_total - $packingjob->is_all_out) . " (" . $packingjob->pieces_sum_total . ")";
|
||||||
echo "</span><td>";
|
echo "</span></td>";
|
||||||
|
|
||||||
|
// Shipping-Icons (inbound)
|
||||||
|
if (ShowShippingIcons) {
|
||||||
|
if (UseShippingStatus) {
|
||||||
|
if (($PackingNoteDetail->status == ShippingInOrganizedStatus) || ($PackingNoteDetail->status == ShippingOrganizedStatus)) {
|
||||||
|
echo "<td style='color:#66FF00; text-align:center;'>";
|
||||||
|
} else {
|
||||||
|
echo "<td style='text-align:center;'>";
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($PackingNoteDetail->is_self_redeliver) {
|
||||||
|
echo '<i class="fa-solid fa-person-walking fa-lg"></i>';
|
||||||
|
} else {
|
||||||
|
if (preg_match('/' . KurierContainsText . '/i', $PackingNoteDetail->shipping_in)) {
|
||||||
|
echo '<i class="fa-solid fa-hand-holding-dollar fa-lg"></i>';
|
||||||
|
}
|
||||||
|
if (preg_match('/' . SpeditionContainsText . '/i', $PackingNoteDetail->shipping_in)) {
|
||||||
|
echo '<i class="fa-solid fa-truck fa-lg"></i>';
|
||||||
|
}
|
||||||
|
if (preg_match('/' . DHLContainsText . '/i', $PackingNoteDetail->shipping_in)) {
|
||||||
|
echo '<i class="fa-brands fa-dhl fa-2xl"></i>';
|
||||||
|
}
|
||||||
|
if (preg_match('/' . LKWContainsText . '/i', $PackingNoteDetail->shipping_in)) {
|
||||||
|
echo '<i class="fa-solid fa-industry fa-lg"></i><i class="fa-solid fa-truck fa-lg"></i>';
|
||||||
|
}
|
||||||
|
if (preg_match('/' . TransporterContainsText . '/i', $PackingNoteDetail->shipping_in)) {
|
||||||
|
echo '<i class="fa-solid fa-industry fa-lg"></i><i class="fa-solid fa-van-shuttle fa-lg"></i>';
|
||||||
|
}
|
||||||
|
if (preg_match('/' . PKWContainsText . '/i', $PackingNoteDetail->shipping_in)) {
|
||||||
|
echo '<i class="fa-solid fa-industry fa-lg"></i><i class="fa-solid fa-car fa-lg"></i>';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
echo "</td>";
|
||||||
|
}
|
||||||
|
|
||||||
|
echo "</tr>";
|
||||||
|
}
|
||||||
|
|
||||||
echo "</tr>";
|
echo "</tr>";
|
||||||
}
|
}
|
||||||
@@ -144,14 +251,9 @@ foreach ($data_output as $packingjob) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function getTimeFromSeconds(string $timestring) {
|
function getTimeFromSeconds(string $timestring) {
|
||||||
|
|
||||||
$hours = floor($timestring / 3600);
|
$hours = floor($timestring / 3600);
|
||||||
$mins = floor($timestring / 60 % 60);
|
$mins = floor($timestring / 60 % 60);
|
||||||
$secs = floor($timestring % 60);
|
$secs = floor($timestring % 60);
|
||||||
|
|
||||||
$timeFormat = sprintf('%02d:%02d', $hours, $mins);
|
$timeFormat = sprintf('%02d:%02d', $hours, $mins);
|
||||||
|
|
||||||
return $timeFormat;
|
return $timeFormat;
|
||||||
}
|
}
|
||||||
|
|
||||||
?>
|
|
||||||
@@ -1,5 +1,6 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
|
|
||||||
error_reporting(E_ALL);
|
error_reporting(E_ALL);
|
||||||
require('../config.php');
|
require('../config.php');
|
||||||
require('../EpiApi.php');
|
require('../EpiApi.php');
|
||||||
@@ -19,20 +20,64 @@ $options = new QROptions([
|
|||||||
'quietzoneSize' => 1
|
'quietzoneSize' => 1
|
||||||
]);
|
]);
|
||||||
|
|
||||||
|
|
||||||
$Epi = new Epirent();
|
$Epi = new Epirent();
|
||||||
|
|
||||||
|
const APP_TZ = 'Europe/Berlin';
|
||||||
|
|
||||||
|
/** Hilfsfunktionen für die Row-Marking-Logik (ohne weitere Änderungen am Rest) */
|
||||||
|
function dt(?string $s): ?DateTimeImmutable {
|
||||||
|
if (!$s)
|
||||||
|
return null;
|
||||||
|
try {
|
||||||
|
return new DateTimeImmutable($s, new DateTimeZone(APP_TZ));
|
||||||
|
} catch (Throwable $e) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function dayStart(DateTimeImmutable $d): DateTimeImmutable {
|
||||||
|
return $d->setTime(0, 0, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
function resolveRowMarkDate($packingjob, $VorbereitungsTimeDetail, $PackingNoteDetail, int $source): ?DateTimeImmutable {
|
||||||
|
$candidate = null;
|
||||||
|
switch ($source) {
|
||||||
|
case 1: $candidate = dt($packingjob->date_start ?? null);
|
||||||
|
break;
|
||||||
|
case 2: $candidate = dt($VorbereitungsTimeDetail->date_start ?? null);
|
||||||
|
break;
|
||||||
|
case 3: $candidate = dt($PackingNoteDetail->date_packing ?? null);
|
||||||
|
break;
|
||||||
|
case 4: $candidate = dt($PackingNoteDetail->date_delivery ?? null);
|
||||||
|
break;
|
||||||
|
default: $candidate = null;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (!$candidate) {
|
||||||
|
$candidate = dt($packingjob->date_start ?? null);
|
||||||
|
}
|
||||||
|
return $candidate ? dayStart($candidate) : null;
|
||||||
|
}
|
||||||
|
|
||||||
|
function rowClassForDate(?DateTimeImmutable $markDate, ?DateTimeImmutable $today): string {
|
||||||
|
if (!$markDate || !$today)
|
||||||
|
return '';
|
||||||
|
if ($markDate == $today)
|
||||||
|
return 'text-dark bg-warning';
|
||||||
|
if ($markDate < $today)
|
||||||
|
return 'bg-danger';
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
|
||||||
|
if (UseDeliveredForCheckOutCompleted) {
|
||||||
|
$result = $Epi->requestEpiApi('/v1/packingnote/open?isco=False&cl=' . Epirent_Mandant);
|
||||||
|
} else {
|
||||||
$result = $Epi->requestEpiApi('/v1/packingnote/open?isci=False&cl=' . Epirent_Mandant);
|
$result = $Epi->requestEpiApi('/v1/packingnote/open?isci=False&cl=' . Epirent_Mandant);
|
||||||
|
}
|
||||||
$data_output = json_decode($result)->payload;
|
$data_output = json_decode($result)->payload;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
if (SortCheckOut == 2) {
|
if (SortCheckOut == 2) {
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// Prüfen, ob $data_output ein Array ist
|
// Prüfen, ob $data_output ein Array ist
|
||||||
if (is_array($data_output)) {
|
if (is_array($data_output)) {
|
||||||
usort($data_output, function ($a, $b) {
|
usort($data_output, function ($a, $b) {
|
||||||
@@ -57,45 +102,54 @@ if (SortCheckOut == 2) {
|
|||||||
|
|
||||||
foreach ($data_output as $packingjob) {
|
foreach ($data_output as $packingjob) {
|
||||||
|
|
||||||
|
$PackingNoteDetail = null;
|
||||||
|
|
||||||
|
if ($packingjob->is_archived != true && UseDeliveredForCheckOutCompleted) {
|
||||||
|
$PackingNoteDetailResult = $Epi->requestEpiApi('/v1/packingnote/' . $packingjob->primary_key . '?cl=' . Epirent_Mandant);
|
||||||
|
$PackingNoteDetail = json_decode($PackingNoteDetailResult)->payload[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
if (
|
||||||
if ($packingjob->is_archived != true) {
|
$packingjob->is_archived != true
|
||||||
|
&& (
|
||||||
|
!UseDeliveredForCheckOutCompleted
|
||||||
|
|| ($PackingNoteDetail->date_delivered !== "0000-00-00" || (int)$PackingNoteDetail->time_delivered !== 0)
|
||||||
|
)
|
||||||
|
&& (int)$PackingNoteDetail->is_all_out !== 0
|
||||||
|
) {
|
||||||
//get OrderDetails
|
//get OrderDetails
|
||||||
$result = $Epi->requestEpiApi('/v1/order/' . $packingjob->order_pk . '?cl=' . Epirent_Mandant);
|
$result = $Epi->requestEpiApi('/v1/order/' . $packingjob->order_pk . '?cl=' . Epirent_Mandant);
|
||||||
|
|
||||||
$orderdetail_output = json_decode($result)->payload[0];
|
$orderdetail_output = json_decode($result)->payload[0];
|
||||||
|
|
||||||
$VorbereitungsTimeDetail;
|
// get PackingNote Details, aber nur wenn nicht schon vor der schleife geholt.
|
||||||
|
if (!UseDeliveredForCheckOutCompleted) {
|
||||||
|
$PackingNoteDetailResult = $Epi->requestEpiApi('/v1/packingnote/' . $packingjob->primary_key . '?cl=' . Epirent_Mandant);
|
||||||
|
$PackingNoteDetail = json_decode($PackingNoteDetailResult)->payload[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
$VorbereitungsTimeDetail = null;
|
||||||
|
|
||||||
foreach ($orderdetail_output->order_schedule as $scheduledetail) {
|
foreach ($orderdetail_output->order_schedule as $scheduledetail) {
|
||||||
|
|
||||||
if ($scheduledetail->name == Vorbereitungs_Zeitvariable) {
|
if ($scheduledetail->name == Vorbereitungs_Zeitvariable) {
|
||||||
$VorbereitungsTimeDetail = $scheduledetail;
|
$VorbereitungsTimeDetail = $scheduledetail;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
//End Of get Order Details
|
|
||||||
|
|
||||||
if (CheckOut_UseDispoStartForRowMarking || ($VorbereitungsTimeDetail->date_start == null)) {
|
// --- Row-Marking Datum bestimmen (konfigurierbar) ---
|
||||||
$date = new DateTime($packingjob->date_start);
|
$today = dayStart(new DateTimeImmutable('today', new DateTimeZone(APP_TZ)));
|
||||||
} else {
|
$todayFilter = $today; // für die Window-Berechnung
|
||||||
$date = new DateTime($VorbereitungsTimeDetail->date_start);
|
$limit = null;
|
||||||
|
if (CheckOut_FutureDays != -1) {
|
||||||
|
$limit = $todayFilter->modify('+' . (int) CheckOut_FutureDays . ' day');
|
||||||
}
|
}
|
||||||
|
|
||||||
$date->setTime(0, 0, 0);
|
$markDate = resolveRowMarkDate($packingjob, $VorbereitungsTimeDetail, $PackingNoteDetail, (int) CheckOutRowMarkSource);
|
||||||
$today = new DateTime();
|
|
||||||
$today->setTime(0, 0, 0);
|
|
||||||
|
|
||||||
$todayFilter = new DateTime();
|
if (CheckOut_FutureDays == -1 || ($markDate && $markDate <= $limit)) {
|
||||||
$todayFilter->setTime(0, 0, 0);
|
$trClass = rowClassForDate($markDate, $today);
|
||||||
if (CheckOut_FutureDays == -1 || $date <= ($todayFilter->modify('+' . CheckOut_FutureDays . ' day'))) {
|
|
||||||
//prüfe, ob entweder unbegrenzte (-1) Anzeige Aktiv ist, oder das Datum kleiner oder Gleich heute + Zukunftsspanne ist
|
|
||||||
if ($date == $today) {
|
|
||||||
|
|
||||||
echo "<tr class='text-dark bg-warning'>";
|
if ($trClass) {
|
||||||
} else if ($date < $today) {
|
echo "<tr class='{$trClass}'>";
|
||||||
echo "<tr class=' bg-danger'>";
|
|
||||||
} else {
|
} else {
|
||||||
echo "<tr>";
|
echo "<tr>";
|
||||||
}
|
}
|
||||||
@@ -107,20 +161,38 @@ foreach ($data_output as $packingjob) {
|
|||||||
}
|
}
|
||||||
echo "<td>" . $packingjob->contact->name . "</td>";
|
echo "<td>" . $packingjob->contact->name . "</td>";
|
||||||
echo "<td>" . $packingjob->event . "</td>";
|
echo "<td>" . $packingjob->event . "</td>";
|
||||||
if ($VorbereitungsTimeDetail->date_start != null) {
|
|
||||||
echo "<td><small>" . date_format(new \DateTime($packingjob->date_start), 'd.m.Y') . " " . getTimeFromSeconds($packingjob->time_start) . "</small><br><i>" . date_format(new \DateTime($VorbereitungsTimeDetail->date_start), 'd.m.Y') . " " . getTimeFromSeconds($VorbereitungsTimeDetail->time_start) . "</i></td>";
|
|
||||||
} else {
|
|
||||||
echo "<td>" . date_format(new \DateTime($packingjob->date_start), 'd.m.Y') . " " . getTimeFromSeconds($packingjob->time_start) . "</td>";
|
|
||||||
}
|
|
||||||
if(!HideCheckInTimeOnCheckout){
|
|
||||||
if (($VorbereitungsTimeDetail->date_end != null)) {
|
|
||||||
echo "<td><small>" . date_format(new \DateTime($packingjob->date_end), 'd.m.Y') . " " . getTimeFromSeconds($packingjob->time_end) . "</small><br><i>" . date_format(new \DateTime($VorbereitungsTimeDetail->date_end), 'd.m.Y') . " " . getTimeFromSeconds($VorbereitungsTimeDetail->time_end) . "</i></td>";
|
|
||||||
} else {
|
|
||||||
echo "<td>" . date_format(new \DateTime($packingjob->date_end), 'd.m.Y') . " " . getTimeFromSeconds($packingjob->time_end) . "</td>";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
echo "<td>";
|
|
||||||
|
|
||||||
|
if (ShowCheckoutTimeOnCheckout || ShowVorbereitungTimeOnCheckout || ShowPackagingTimeOnCheckout || ShowDeliveryTimeOnCheckout) { echo "<td>";}
|
||||||
|
|
||||||
|
|
||||||
|
if (ShowCheckoutTimeOnCheckout && $packingjob->date_start != null) {
|
||||||
|
echoMarkedTimeLine($packingjob->date_start, (int) $packingjob->time_start, $today, ShowTimesOnCheckout);
|
||||||
|
}
|
||||||
|
if (ShowVorbereitungTimeOnCheckout && $VorbereitungsTimeDetail && $VorbereitungsTimeDetail->date_start != null) {
|
||||||
|
if (ShowCheckoutTimeOnCheckout) {
|
||||||
|
echo "<br>";
|
||||||
|
}
|
||||||
|
echoMarkedTimeLine($VorbereitungsTimeDetail->date_start, (int) $VorbereitungsTimeDetail->time_start, $today, ShowTimesOnCheckout);
|
||||||
|
}
|
||||||
|
if (ShowPackagingTimeOnCheckout && $PackingNoteDetail && $PackingNoteDetail->date_packing != null) {
|
||||||
|
if (ShowCheckoutTimeOnCheckout || ShowVorbereitungTimeOnCheckout) {
|
||||||
|
echo "<br>";
|
||||||
|
}
|
||||||
|
echoMarkedTimeLine($PackingNoteDetail->date_packing, (int) $PackingNoteDetail->time_packing, $today, ShowTimesOnCheckout);
|
||||||
|
}
|
||||||
|
if (ShowDeliveryTimeOnCheckout && $PackingNoteDetail && $PackingNoteDetail->date_delivery != null) {
|
||||||
|
if (ShowCheckoutTimeOnCheckout || ShowVorbereitungTimeOnCheckout || ShowPackagingTimeOnCheckout) {
|
||||||
|
echo "<br>";
|
||||||
|
}
|
||||||
|
echoMarkedTimeLine($PackingNoteDetail->date_delivery, (int) $PackingNoteDetail->time_delivery, $today, ShowTimesOnCheckout);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if (ShowCheckoutTimeOnCheckout || ShowVorbereitungTimeOnCheckout || ShowPackagingTimeOnCheckout || ShowDeliveryTimeOnCheckout) {
|
||||||
|
echo "</td>";
|
||||||
|
}
|
||||||
|
|
||||||
|
echo "<td>";
|
||||||
|
|
||||||
if ($packingjob->is_all_out == 0) {
|
if ($packingjob->is_all_out == 0) {
|
||||||
echo "<span class='badge badge-success'>";
|
echo "<span class='badge badge-success'>";
|
||||||
@@ -132,12 +204,66 @@ foreach ($data_output as $packingjob) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
echo ($packingjob->pieces_sum_total - abs($packingjob->is_all_out)) . "/" . $packingjob->pieces_sum_total;
|
echo ($packingjob->pieces_sum_total - abs($packingjob->is_all_out)) . "/" . $packingjob->pieces_sum_total;
|
||||||
echo "</span><td>";
|
echo "</span></td>";
|
||||||
|
|
||||||
|
if (ShowShippingIcons) {
|
||||||
|
|
||||||
|
if (UseShippingStatus) {
|
||||||
|
if (($PackingNoteDetail->status == ShippingOutOrganizedStatus) || ($PackingNoteDetail->status == ShippingOrganizedStatus)) {
|
||||||
|
echo "<td style='color:#66FF00; text-align:center;'>";
|
||||||
|
} else {
|
||||||
|
echo "<td style='text-align:center;'>";
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($PackingNoteDetail->is_self_pickup) {
|
||||||
|
echo '<i class="fa-solid fa-person-walking fa-lg"></i>';
|
||||||
|
} else {
|
||||||
|
if (preg_match('/' . KurierContainsText . '/i', $PackingNoteDetail->shipping_out)) {
|
||||||
|
echo '<i class="fa-solid fa-hand-holding-dollar fa-lg"></i>';
|
||||||
|
}
|
||||||
|
if (preg_match('/' . SpeditionContainsText . '/i', $PackingNoteDetail->shipping_out)) {
|
||||||
|
echo '<i class="fa-solid fa-truck fa-lg"></i>';
|
||||||
|
}
|
||||||
|
if (preg_match('/' . DHLContainsText . '/i', $PackingNoteDetail->shipping_out)) {
|
||||||
|
echo '<i class="fa-brands fa-dhl fa-2xl"></i>';
|
||||||
|
}
|
||||||
|
if (preg_match('/' . LKWContainsText . '/i', $PackingNoteDetail->shipping_out)) {
|
||||||
|
echo '<i class="fa-solid fa-industry fa-lg"></i><i class="fa-solid fa-truck fa-lg"></i>';
|
||||||
|
}
|
||||||
|
if (preg_match('/' . TransporterContainsText . '/i', $PackingNoteDetail->shipping_out)) {
|
||||||
|
echo '<i class="fa-solid fa-industry fa-lg"></i><i class="fa-solid fa-van-shuttle fa-lg"></i>';
|
||||||
|
}
|
||||||
|
if (preg_match('/' . PKWContainsText . '/i', $PackingNoteDetail->shipping_out)) {
|
||||||
|
echo '<i class="fa-solid fa-industry fa-lg"></i><i class="fa-solid fa-car fa-lg"></i>';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
echo "</td>";
|
||||||
|
}
|
||||||
|
|
||||||
|
echo "</tr>";
|
||||||
|
}
|
||||||
|
|
||||||
echo "</tr>";
|
echo "</tr>";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function echoMarkedTimeLine(?string $dateStr, ?int $timeSeconds, DateTimeImmutable $today, $ReturnTime): void {
|
||||||
|
if (!$dateStr)
|
||||||
|
return;
|
||||||
|
$d = dt($dateStr);
|
||||||
|
if (!$d)
|
||||||
|
return;
|
||||||
|
|
||||||
|
$mark = dayStart($d);
|
||||||
|
$cls = rowClassForDate($mark, $today);
|
||||||
|
|
||||||
|
echo $cls ? "<span class=\"{$cls}\">" : "";
|
||||||
|
echo date_format(new \DateTime($dateStr), 'd.m.Y');
|
||||||
|
if($ReturnTime){echo " ".getTimeFromSeconds((string) $timeSeconds);}
|
||||||
|
echo $cls ? "</span>" : "";
|
||||||
|
}
|
||||||
|
|
||||||
function getTimeFromSeconds(string $timestring) {
|
function getTimeFromSeconds(string $timestring) {
|
||||||
|
|
||||||
$hours = floor($timestring / 3600);
|
$hours = floor($timestring / 3600);
|
||||||
|
|||||||
10663
src/fa/css/all.css
Normal file
10663
src/fa/css/all.css
Normal file
File diff suppressed because it is too large
Load Diff
9
src/fa/css/all.min.css
vendored
Normal file
9
src/fa/css/all.min.css
vendored
Normal file
File diff suppressed because one or more lines are too long
2219
src/fa/css/brands.css
Normal file
2219
src/fa/css/brands.css
Normal file
File diff suppressed because it is too large
Load Diff
6
src/fa/css/brands.min.css
vendored
Normal file
6
src/fa/css/brands.min.css
vendored
Normal file
File diff suppressed because one or more lines are too long
8361
src/fa/css/fontawesome.css
vendored
Normal file
8361
src/fa/css/fontawesome.css
vendored
Normal file
File diff suppressed because it is too large
Load Diff
8
src/fa/css/fontawesome.min.css
vendored
Normal file
8
src/fa/css/fontawesome.min.css
vendored
Normal file
File diff suppressed because one or more lines are too long
31
src/fa/css/regular.css
Normal file
31
src/fa/css/regular.css
Normal file
@@ -0,0 +1,31 @@
|
|||||||
|
/*!
|
||||||
|
* Font Awesome Free 7.1.0 by @fontawesome - https://fontawesome.com
|
||||||
|
* License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License)
|
||||||
|
* Copyright 2025 Fonticons, Inc.
|
||||||
|
*/
|
||||||
|
:root, :host {
|
||||||
|
--fa-family-classic: "Font Awesome 7 Free";
|
||||||
|
--fa-font-regular: normal 400 1em/1 var(--fa-family-classic);
|
||||||
|
/* deprecated: this older custom property will be removed next major release */
|
||||||
|
--fa-style-family-classic: var(--fa-family-classic);
|
||||||
|
}
|
||||||
|
|
||||||
|
@font-face {
|
||||||
|
font-family: "Font Awesome 7 Free";
|
||||||
|
font-style: normal;
|
||||||
|
font-weight: 400;
|
||||||
|
font-display: block;
|
||||||
|
src: url("../webfonts/fa-regular-400.woff2");
|
||||||
|
}
|
||||||
|
.far {
|
||||||
|
--fa-family: var(--fa-family-classic);
|
||||||
|
--fa-style: 400;
|
||||||
|
}
|
||||||
|
|
||||||
|
.fa-classic {
|
||||||
|
--fa-family: var(--fa-family-classic);
|
||||||
|
}
|
||||||
|
|
||||||
|
.fa-regular {
|
||||||
|
--fa-style: 400;
|
||||||
|
}
|
||||||
6
src/fa/css/regular.min.css
vendored
Normal file
6
src/fa/css/regular.min.css
vendored
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
/*!
|
||||||
|
* Font Awesome Free 7.1.0 by @fontawesome - https://fontawesome.com
|
||||||
|
* License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License)
|
||||||
|
* Copyright 2025 Fonticons, Inc.
|
||||||
|
*/
|
||||||
|
:host,:root{--fa-family-classic:"Font Awesome 7 Free";--fa-font-regular:normal 400 1em/1 var(--fa-family-classic);--fa-style-family-classic:var(--fa-family-classic)}@font-face{font-family:"Font Awesome 7 Free";font-style:normal;font-weight:400;font-display:block;src:url(../webfonts/fa-regular-400.woff2)}.far{--fa-style:400}.fa-classic,.far{--fa-family:var(--fa-family-classic)}.fa-regular{--fa-style:400}
|
||||||
31
src/fa/css/solid.css
Normal file
31
src/fa/css/solid.css
Normal file
@@ -0,0 +1,31 @@
|
|||||||
|
/*!
|
||||||
|
* Font Awesome Free 7.1.0 by @fontawesome - https://fontawesome.com
|
||||||
|
* License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License)
|
||||||
|
* Copyright 2025 Fonticons, Inc.
|
||||||
|
*/
|
||||||
|
:root, :host {
|
||||||
|
--fa-family-classic: "Font Awesome 7 Free";
|
||||||
|
--fa-font-solid: normal 900 1em/1 var(--fa-family-classic);
|
||||||
|
/* deprecated: this older custom property will be removed next major release */
|
||||||
|
--fa-style-family-classic: var(--fa-family-classic);
|
||||||
|
}
|
||||||
|
|
||||||
|
@font-face {
|
||||||
|
font-family: "Font Awesome 7 Free";
|
||||||
|
font-style: normal;
|
||||||
|
font-weight: 900;
|
||||||
|
font-display: block;
|
||||||
|
src: url("../webfonts/fa-solid-900.woff2");
|
||||||
|
}
|
||||||
|
.fas {
|
||||||
|
--fa-family: var(--fa-family-classic);
|
||||||
|
--fa-style: 900;
|
||||||
|
}
|
||||||
|
|
||||||
|
.fa-classic {
|
||||||
|
--fa-family: var(--fa-family-classic);
|
||||||
|
}
|
||||||
|
|
||||||
|
.fa-solid {
|
||||||
|
--fa-style: 900;
|
||||||
|
}
|
||||||
6
src/fa/css/solid.min.css
vendored
Normal file
6
src/fa/css/solid.min.css
vendored
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
/*!
|
||||||
|
* Font Awesome Free 7.1.0 by @fontawesome - https://fontawesome.com
|
||||||
|
* License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License)
|
||||||
|
* Copyright 2025 Fonticons, Inc.
|
||||||
|
*/
|
||||||
|
:host,:root{--fa-family-classic:"Font Awesome 7 Free";--fa-font-solid:normal 900 1em/1 var(--fa-family-classic);--fa-style-family-classic:var(--fa-family-classic)}@font-face{font-family:"Font Awesome 7 Free";font-style:normal;font-weight:900;font-display:block;src:url(../webfonts/fa-solid-900.woff2)}.fas{--fa-style:900}.fa-classic,.fas{--fa-family:var(--fa-family-classic)}.fa-solid{--fa-style:900}
|
||||||
556
src/fa/css/svg-with-js.css
Normal file
556
src/fa/css/svg-with-js.css
Normal file
@@ -0,0 +1,556 @@
|
|||||||
|
/*!
|
||||||
|
* Font Awesome Free 7.1.0 by @fontawesome - https://fontawesome.com
|
||||||
|
* License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License)
|
||||||
|
* Copyright 2025 Fonticons, Inc.
|
||||||
|
*/
|
||||||
|
:root, :host {
|
||||||
|
--fa-font-solid: normal 900 1em/1 "Font Awesome 7 Free";
|
||||||
|
--fa-font-regular: normal 400 1em/1 "Font Awesome 7 Free";
|
||||||
|
--fa-font-light: normal 300 1em/1 "Font Awesome 7 Pro";
|
||||||
|
--fa-font-thin: normal 100 1em/1 "Font Awesome 7 Pro";
|
||||||
|
--fa-font-duotone: normal 900 1em/1 "Font Awesome 7 Duotone";
|
||||||
|
--fa-font-duotone-regular: normal 400 1em/1 "Font Awesome 7 Duotone";
|
||||||
|
--fa-font-duotone-light: normal 300 1em/1 "Font Awesome 7 Duotone";
|
||||||
|
--fa-font-duotone-thin: normal 100 1em/1 "Font Awesome 7 Duotone";
|
||||||
|
--fa-font-brands: normal 400 1em/1 "Font Awesome 7 Brands";
|
||||||
|
--fa-font-sharp-solid: normal 900 1em/1 "Font Awesome 7 Sharp";
|
||||||
|
--fa-font-sharp-regular: normal 400 1em/1 "Font Awesome 7 Sharp";
|
||||||
|
--fa-font-sharp-light: normal 300 1em/1 "Font Awesome 7 Sharp";
|
||||||
|
--fa-font-sharp-thin: normal 100 1em/1 "Font Awesome 7 Sharp";
|
||||||
|
--fa-font-sharp-duotone-solid: normal 900 1em/1 "Font Awesome 7 Sharp Duotone";
|
||||||
|
--fa-font-sharp-duotone-regular: normal 400 1em/1 "Font Awesome 7 Sharp Duotone";
|
||||||
|
--fa-font-sharp-duotone-light: normal 300 1em/1 "Font Awesome 7 Sharp Duotone";
|
||||||
|
--fa-font-sharp-duotone-thin: normal 100 1em/1 "Font Awesome 7 Sharp Duotone";
|
||||||
|
--fa-font-slab-regular: normal 400 1em/1 "Font Awesome 7 Slab";
|
||||||
|
--fa-font-slab-press-regular: normal 400 1em/1 "Font Awesome 7 Slab Press";
|
||||||
|
--fa-font-whiteboard-semibold: normal 600 1em/1 "Font Awesome 7 Whiteboard";
|
||||||
|
--fa-font-thumbprint-light: normal 300 1em/1 "Font Awesome 7 Thumbprint";
|
||||||
|
--fa-font-notdog-solid: normal 900 1em/1 "Font Awesome 7 Notdog";
|
||||||
|
--fa-font-notdog-duo-solid: normal 900 1em/1 "Font Awesome 7 Notdog Duo";
|
||||||
|
--fa-font-etch-solid: normal 900 1em/1 "Font Awesome 7 Etch";
|
||||||
|
--fa-font-jelly-regular: normal 400 1em/1 "Font Awesome 7 Jelly";
|
||||||
|
--fa-font-jelly-fill-regular: normal 400 1em/1 "Font Awesome 7 Jelly Fill";
|
||||||
|
--fa-font-jelly-duo-regular: normal 400 1em/1 "Font Awesome 7 Jelly Duo";
|
||||||
|
--fa-font-chisel-regular: normal 400 1em/1 "Font Awesome 7 Chisel";
|
||||||
|
--fa-font-utility-semibold: normal 600 1em/1 "Font Awesome 7 Utility";
|
||||||
|
--fa-font-utility-duo-semibold: normal 600 1em/1 "Font Awesome 7 Utility Duo";
|
||||||
|
--fa-font-utility-fill-semibold: normal 600 1em/1 "Font Awesome 7 Utility Fill";
|
||||||
|
}
|
||||||
|
|
||||||
|
.svg-inline--fa {
|
||||||
|
box-sizing: content-box;
|
||||||
|
display: var(--fa-display, inline-block);
|
||||||
|
height: 1em;
|
||||||
|
overflow: visible;
|
||||||
|
vertical-align: -0.125em;
|
||||||
|
width: var(--fa-width, 1.25em);
|
||||||
|
}
|
||||||
|
.svg-inline--fa.fa-2xs {
|
||||||
|
vertical-align: 0.1em;
|
||||||
|
}
|
||||||
|
.svg-inline--fa.fa-xs {
|
||||||
|
vertical-align: 0em;
|
||||||
|
}
|
||||||
|
.svg-inline--fa.fa-sm {
|
||||||
|
vertical-align: -0.0714285714em;
|
||||||
|
}
|
||||||
|
.svg-inline--fa.fa-lg {
|
||||||
|
vertical-align: -0.2em;
|
||||||
|
}
|
||||||
|
.svg-inline--fa.fa-xl {
|
||||||
|
vertical-align: -0.25em;
|
||||||
|
}
|
||||||
|
.svg-inline--fa.fa-2xl {
|
||||||
|
vertical-align: -0.3125em;
|
||||||
|
}
|
||||||
|
.svg-inline--fa.fa-pull-left,
|
||||||
|
.svg-inline--fa .fa-pull-start {
|
||||||
|
float: inline-start;
|
||||||
|
margin-inline-end: var(--fa-pull-margin, 0.3em);
|
||||||
|
}
|
||||||
|
.svg-inline--fa.fa-pull-right,
|
||||||
|
.svg-inline--fa .fa-pull-end {
|
||||||
|
float: inline-end;
|
||||||
|
margin-inline-start: var(--fa-pull-margin, 0.3em);
|
||||||
|
}
|
||||||
|
.svg-inline--fa.fa-li {
|
||||||
|
width: var(--fa-li-width, 2em);
|
||||||
|
inset-inline-start: calc(-1 * var(--fa-li-width, 2em));
|
||||||
|
inset-block-start: 0.25em; /* syncing vertical alignment with Web Font rendering */
|
||||||
|
}
|
||||||
|
|
||||||
|
.fa-layers-counter, .fa-layers-text {
|
||||||
|
display: inline-block;
|
||||||
|
position: absolute;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.fa-layers {
|
||||||
|
display: inline-block;
|
||||||
|
height: 1em;
|
||||||
|
position: relative;
|
||||||
|
text-align: center;
|
||||||
|
vertical-align: -0.125em;
|
||||||
|
width: var(--fa-width, 1.25em);
|
||||||
|
}
|
||||||
|
.fa-layers .svg-inline--fa {
|
||||||
|
inset: 0;
|
||||||
|
margin: auto;
|
||||||
|
position: absolute;
|
||||||
|
transform-origin: center center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.fa-layers-text {
|
||||||
|
left: 50%;
|
||||||
|
top: 50%;
|
||||||
|
transform: translate(-50%, -50%);
|
||||||
|
transform-origin: center center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.fa-layers-counter {
|
||||||
|
background-color: var(--fa-counter-background-color, #ff253a);
|
||||||
|
border-radius: var(--fa-counter-border-radius, 1em);
|
||||||
|
box-sizing: border-box;
|
||||||
|
color: var(--fa-inverse, #fff);
|
||||||
|
line-height: var(--fa-counter-line-height, 1);
|
||||||
|
max-width: var(--fa-counter-max-width, 5em);
|
||||||
|
min-width: var(--fa-counter-min-width, 1.5em);
|
||||||
|
overflow: hidden;
|
||||||
|
padding: var(--fa-counter-padding, 0.25em 0.5em);
|
||||||
|
right: var(--fa-right, 0);
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
top: var(--fa-top, 0);
|
||||||
|
transform: scale(var(--fa-counter-scale, 0.25));
|
||||||
|
transform-origin: top right;
|
||||||
|
}
|
||||||
|
|
||||||
|
.fa-layers-bottom-right {
|
||||||
|
bottom: var(--fa-bottom, 0);
|
||||||
|
right: var(--fa-right, 0);
|
||||||
|
top: auto;
|
||||||
|
transform: scale(var(--fa-layers-scale, 0.25));
|
||||||
|
transform-origin: bottom right;
|
||||||
|
}
|
||||||
|
|
||||||
|
.fa-layers-bottom-left {
|
||||||
|
bottom: var(--fa-bottom, 0);
|
||||||
|
left: var(--fa-left, 0);
|
||||||
|
right: auto;
|
||||||
|
top: auto;
|
||||||
|
transform: scale(var(--fa-layers-scale, 0.25));
|
||||||
|
transform-origin: bottom left;
|
||||||
|
}
|
||||||
|
|
||||||
|
.fa-layers-top-right {
|
||||||
|
top: var(--fa-top, 0);
|
||||||
|
right: var(--fa-right, 0);
|
||||||
|
transform: scale(var(--fa-layers-scale, 0.25));
|
||||||
|
transform-origin: top right;
|
||||||
|
}
|
||||||
|
|
||||||
|
.fa-layers-top-left {
|
||||||
|
left: var(--fa-left, 0);
|
||||||
|
right: auto;
|
||||||
|
top: var(--fa-top, 0);
|
||||||
|
transform: scale(var(--fa-layers-scale, 0.25));
|
||||||
|
transform-origin: top left;
|
||||||
|
}
|
||||||
|
|
||||||
|
.fa-1x {
|
||||||
|
font-size: 1em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.fa-2x {
|
||||||
|
font-size: 2em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.fa-3x {
|
||||||
|
font-size: 3em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.fa-4x {
|
||||||
|
font-size: 4em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.fa-5x {
|
||||||
|
font-size: 5em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.fa-6x {
|
||||||
|
font-size: 6em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.fa-7x {
|
||||||
|
font-size: 7em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.fa-8x {
|
||||||
|
font-size: 8em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.fa-9x {
|
||||||
|
font-size: 9em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.fa-10x {
|
||||||
|
font-size: 10em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.fa-2xs {
|
||||||
|
font-size: calc(10 / 16 * 1em); /* converts a 10px size into an em-based value that's relative to the scale's 16px base */
|
||||||
|
line-height: calc(1 / 10 * 1em); /* sets the line-height of the icon back to that of it's parent */
|
||||||
|
vertical-align: calc((6 / 10 - 0.375) * 1em); /* vertically centers the icon taking into account the surrounding text's descender */
|
||||||
|
}
|
||||||
|
|
||||||
|
.fa-xs {
|
||||||
|
font-size: calc(12 / 16 * 1em); /* converts a 12px size into an em-based value that's relative to the scale's 16px base */
|
||||||
|
line-height: calc(1 / 12 * 1em); /* sets the line-height of the icon back to that of it's parent */
|
||||||
|
vertical-align: calc((6 / 12 - 0.375) * 1em); /* vertically centers the icon taking into account the surrounding text's descender */
|
||||||
|
}
|
||||||
|
|
||||||
|
.fa-sm {
|
||||||
|
font-size: calc(14 / 16 * 1em); /* converts a 14px size into an em-based value that's relative to the scale's 16px base */
|
||||||
|
line-height: calc(1 / 14 * 1em); /* sets the line-height of the icon back to that of it's parent */
|
||||||
|
vertical-align: calc((6 / 14 - 0.375) * 1em); /* vertically centers the icon taking into account the surrounding text's descender */
|
||||||
|
}
|
||||||
|
|
||||||
|
.fa-lg {
|
||||||
|
font-size: calc(20 / 16 * 1em); /* converts a 20px size into an em-based value that's relative to the scale's 16px base */
|
||||||
|
line-height: calc(1 / 20 * 1em); /* sets the line-height of the icon back to that of it's parent */
|
||||||
|
vertical-align: calc((6 / 20 - 0.375) * 1em); /* vertically centers the icon taking into account the surrounding text's descender */
|
||||||
|
}
|
||||||
|
|
||||||
|
.fa-xl {
|
||||||
|
font-size: calc(24 / 16 * 1em); /* converts a 24px size into an em-based value that's relative to the scale's 16px base */
|
||||||
|
line-height: calc(1 / 24 * 1em); /* sets the line-height of the icon back to that of it's parent */
|
||||||
|
vertical-align: calc((6 / 24 - 0.375) * 1em); /* vertically centers the icon taking into account the surrounding text's descender */
|
||||||
|
}
|
||||||
|
|
||||||
|
.fa-2xl {
|
||||||
|
font-size: calc(32 / 16 * 1em); /* converts a 32px size into an em-based value that's relative to the scale's 16px base */
|
||||||
|
line-height: calc(1 / 32 * 1em); /* sets the line-height of the icon back to that of it's parent */
|
||||||
|
vertical-align: calc((6 / 32 - 0.375) * 1em); /* vertically centers the icon taking into account the surrounding text's descender */
|
||||||
|
}
|
||||||
|
|
||||||
|
.fa-width-auto {
|
||||||
|
--fa-width: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.fa-fw,
|
||||||
|
.fa-width-fixed {
|
||||||
|
--fa-width: 1.25em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.fa-ul {
|
||||||
|
list-style-type: none;
|
||||||
|
margin-inline-start: var(--fa-li-margin, 2.5em);
|
||||||
|
padding-inline-start: 0;
|
||||||
|
}
|
||||||
|
.fa-ul > li {
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
|
||||||
|
.fa-li {
|
||||||
|
inset-inline-start: calc(-1 * var(--fa-li-width, 2em));
|
||||||
|
position: absolute;
|
||||||
|
text-align: center;
|
||||||
|
width: var(--fa-li-width, 2em);
|
||||||
|
line-height: inherit;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Heads Up: Bordered Icons will not be supported in the future!
|
||||||
|
- This feature will be deprecated in the next major release of Font Awesome (v8)!
|
||||||
|
- You may continue to use it in this version *v7), but it will not be supported in Font Awesome v8.
|
||||||
|
*/
|
||||||
|
/* Notes:
|
||||||
|
* --@{v.$css-prefix}-border-width = 1/16 by default (to render as ~1px based on a 16px default font-size)
|
||||||
|
* --@{v.$css-prefix}-border-padding =
|
||||||
|
** 3/16 for vertical padding (to give ~2px of vertical whitespace around an icon considering it's vertical alignment)
|
||||||
|
** 4/16 for horizontal padding (to give ~4px of horizontal whitespace around an icon)
|
||||||
|
*/
|
||||||
|
.fa-border {
|
||||||
|
border-color: var(--fa-border-color, #eee);
|
||||||
|
border-radius: var(--fa-border-radius, 0.1em);
|
||||||
|
border-style: var(--fa-border-style, solid);
|
||||||
|
border-width: var(--fa-border-width, 0.0625em);
|
||||||
|
box-sizing: var(--fa-border-box-sizing, content-box);
|
||||||
|
padding: var(--fa-border-padding, 0.1875em 0.25em);
|
||||||
|
}
|
||||||
|
|
||||||
|
.fa-pull-left,
|
||||||
|
.fa-pull-start {
|
||||||
|
float: inline-start;
|
||||||
|
margin-inline-end: var(--fa-pull-margin, 0.3em);
|
||||||
|
}
|
||||||
|
|
||||||
|
.fa-pull-right,
|
||||||
|
.fa-pull-end {
|
||||||
|
float: inline-end;
|
||||||
|
margin-inline-start: var(--fa-pull-margin, 0.3em);
|
||||||
|
}
|
||||||
|
|
||||||
|
.fa-beat {
|
||||||
|
animation-name: fa-beat;
|
||||||
|
animation-delay: var(--fa-animation-delay, 0s);
|
||||||
|
animation-direction: var(--fa-animation-direction, normal);
|
||||||
|
animation-duration: var(--fa-animation-duration, 1s);
|
||||||
|
animation-iteration-count: var(--fa-animation-iteration-count, infinite);
|
||||||
|
animation-timing-function: var(--fa-animation-timing, ease-in-out);
|
||||||
|
}
|
||||||
|
|
||||||
|
.fa-bounce {
|
||||||
|
animation-name: fa-bounce;
|
||||||
|
animation-delay: var(--fa-animation-delay, 0s);
|
||||||
|
animation-direction: var(--fa-animation-direction, normal);
|
||||||
|
animation-duration: var(--fa-animation-duration, 1s);
|
||||||
|
animation-iteration-count: var(--fa-animation-iteration-count, infinite);
|
||||||
|
animation-timing-function: var(--fa-animation-timing, cubic-bezier(0.28, 0.84, 0.42, 1));
|
||||||
|
}
|
||||||
|
|
||||||
|
.fa-fade {
|
||||||
|
animation-name: fa-fade;
|
||||||
|
animation-delay: var(--fa-animation-delay, 0s);
|
||||||
|
animation-direction: var(--fa-animation-direction, normal);
|
||||||
|
animation-duration: var(--fa-animation-duration, 1s);
|
||||||
|
animation-iteration-count: var(--fa-animation-iteration-count, infinite);
|
||||||
|
animation-timing-function: var(--fa-animation-timing, cubic-bezier(0.4, 0, 0.6, 1));
|
||||||
|
}
|
||||||
|
|
||||||
|
.fa-beat-fade {
|
||||||
|
animation-name: fa-beat-fade;
|
||||||
|
animation-delay: var(--fa-animation-delay, 0s);
|
||||||
|
animation-direction: var(--fa-animation-direction, normal);
|
||||||
|
animation-duration: var(--fa-animation-duration, 1s);
|
||||||
|
animation-iteration-count: var(--fa-animation-iteration-count, infinite);
|
||||||
|
animation-timing-function: var(--fa-animation-timing, cubic-bezier(0.4, 0, 0.6, 1));
|
||||||
|
}
|
||||||
|
|
||||||
|
.fa-flip {
|
||||||
|
animation-name: fa-flip;
|
||||||
|
animation-delay: var(--fa-animation-delay, 0s);
|
||||||
|
animation-direction: var(--fa-animation-direction, normal);
|
||||||
|
animation-duration: var(--fa-animation-duration, 1s);
|
||||||
|
animation-iteration-count: var(--fa-animation-iteration-count, infinite);
|
||||||
|
animation-timing-function: var(--fa-animation-timing, ease-in-out);
|
||||||
|
}
|
||||||
|
|
||||||
|
.fa-shake {
|
||||||
|
animation-name: fa-shake;
|
||||||
|
animation-delay: var(--fa-animation-delay, 0s);
|
||||||
|
animation-direction: var(--fa-animation-direction, normal);
|
||||||
|
animation-duration: var(--fa-animation-duration, 1s);
|
||||||
|
animation-iteration-count: var(--fa-animation-iteration-count, infinite);
|
||||||
|
animation-timing-function: var(--fa-animation-timing, linear);
|
||||||
|
}
|
||||||
|
|
||||||
|
.fa-spin {
|
||||||
|
animation-name: fa-spin;
|
||||||
|
animation-delay: var(--fa-animation-delay, 0s);
|
||||||
|
animation-direction: var(--fa-animation-direction, normal);
|
||||||
|
animation-duration: var(--fa-animation-duration, 2s);
|
||||||
|
animation-iteration-count: var(--fa-animation-iteration-count, infinite);
|
||||||
|
animation-timing-function: var(--fa-animation-timing, linear);
|
||||||
|
}
|
||||||
|
|
||||||
|
.fa-spin-reverse {
|
||||||
|
--fa-animation-direction: reverse;
|
||||||
|
}
|
||||||
|
|
||||||
|
.fa-pulse,
|
||||||
|
.fa-spin-pulse {
|
||||||
|
animation-name: fa-spin;
|
||||||
|
animation-direction: var(--fa-animation-direction, normal);
|
||||||
|
animation-duration: var(--fa-animation-duration, 1s);
|
||||||
|
animation-iteration-count: var(--fa-animation-iteration-count, infinite);
|
||||||
|
animation-timing-function: var(--fa-animation-timing, steps(8));
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (prefers-reduced-motion: reduce) {
|
||||||
|
.fa-beat,
|
||||||
|
.fa-bounce,
|
||||||
|
.fa-fade,
|
||||||
|
.fa-beat-fade,
|
||||||
|
.fa-flip,
|
||||||
|
.fa-pulse,
|
||||||
|
.fa-shake,
|
||||||
|
.fa-spin,
|
||||||
|
.fa-spin-pulse {
|
||||||
|
animation: none !important;
|
||||||
|
transition: none !important;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@keyframes fa-beat {
|
||||||
|
0%, 90% {
|
||||||
|
transform: scale(1);
|
||||||
|
}
|
||||||
|
45% {
|
||||||
|
transform: scale(var(--fa-beat-scale, 1.25));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@keyframes fa-bounce {
|
||||||
|
0% {
|
||||||
|
transform: scale(1, 1) translateY(0);
|
||||||
|
}
|
||||||
|
10% {
|
||||||
|
transform: scale(var(--fa-bounce-start-scale-x, 1.1), var(--fa-bounce-start-scale-y, 0.9)) translateY(0);
|
||||||
|
}
|
||||||
|
30% {
|
||||||
|
transform: scale(var(--fa-bounce-jump-scale-x, 0.9), var(--fa-bounce-jump-scale-y, 1.1)) translateY(var(--fa-bounce-height, -0.5em));
|
||||||
|
}
|
||||||
|
50% {
|
||||||
|
transform: scale(var(--fa-bounce-land-scale-x, 1.05), var(--fa-bounce-land-scale-y, 0.95)) translateY(0);
|
||||||
|
}
|
||||||
|
57% {
|
||||||
|
transform: scale(1, 1) translateY(var(--fa-bounce-rebound, -0.125em));
|
||||||
|
}
|
||||||
|
64% {
|
||||||
|
transform: scale(1, 1) translateY(0);
|
||||||
|
}
|
||||||
|
100% {
|
||||||
|
transform: scale(1, 1) translateY(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@keyframes fa-fade {
|
||||||
|
50% {
|
||||||
|
opacity: var(--fa-fade-opacity, 0.4);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@keyframes fa-beat-fade {
|
||||||
|
0%, 100% {
|
||||||
|
opacity: var(--fa-beat-fade-opacity, 0.4);
|
||||||
|
transform: scale(1);
|
||||||
|
}
|
||||||
|
50% {
|
||||||
|
opacity: 1;
|
||||||
|
transform: scale(var(--fa-beat-fade-scale, 1.125));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@keyframes fa-flip {
|
||||||
|
50% {
|
||||||
|
transform: rotate3d(var(--fa-flip-x, 0), var(--fa-flip-y, 1), var(--fa-flip-z, 0), var(--fa-flip-angle, -180deg));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@keyframes fa-shake {
|
||||||
|
0% {
|
||||||
|
transform: rotate(-15deg);
|
||||||
|
}
|
||||||
|
4% {
|
||||||
|
transform: rotate(15deg);
|
||||||
|
}
|
||||||
|
8%, 24% {
|
||||||
|
transform: rotate(-18deg);
|
||||||
|
}
|
||||||
|
12%, 28% {
|
||||||
|
transform: rotate(18deg);
|
||||||
|
}
|
||||||
|
16% {
|
||||||
|
transform: rotate(-22deg);
|
||||||
|
}
|
||||||
|
20% {
|
||||||
|
transform: rotate(22deg);
|
||||||
|
}
|
||||||
|
32% {
|
||||||
|
transform: rotate(-12deg);
|
||||||
|
}
|
||||||
|
36% {
|
||||||
|
transform: rotate(12deg);
|
||||||
|
}
|
||||||
|
40%, 100% {
|
||||||
|
transform: rotate(0deg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@keyframes fa-spin {
|
||||||
|
0% {
|
||||||
|
transform: rotate(0deg);
|
||||||
|
}
|
||||||
|
100% {
|
||||||
|
transform: rotate(360deg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.fa-rotate-90 {
|
||||||
|
transform: rotate(90deg);
|
||||||
|
}
|
||||||
|
|
||||||
|
.fa-rotate-180 {
|
||||||
|
transform: rotate(180deg);
|
||||||
|
}
|
||||||
|
|
||||||
|
.fa-rotate-270 {
|
||||||
|
transform: rotate(270deg);
|
||||||
|
}
|
||||||
|
|
||||||
|
.fa-flip-horizontal {
|
||||||
|
transform: scale(-1, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
.fa-flip-vertical {
|
||||||
|
transform: scale(1, -1);
|
||||||
|
}
|
||||||
|
|
||||||
|
.fa-flip-both,
|
||||||
|
.fa-flip-horizontal.fa-flip-vertical {
|
||||||
|
transform: scale(-1, -1);
|
||||||
|
}
|
||||||
|
|
||||||
|
.fa-rotate-by {
|
||||||
|
transform: rotate(var(--fa-rotate-angle, 0));
|
||||||
|
}
|
||||||
|
|
||||||
|
.svg-inline--fa .fa-primary {
|
||||||
|
fill: var(--fa-primary-color, currentColor);
|
||||||
|
opacity: var(--fa-primary-opacity, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
.svg-inline--fa .fa-secondary {
|
||||||
|
fill: var(--fa-secondary-color, currentColor);
|
||||||
|
opacity: var(--fa-secondary-opacity, 0.4);
|
||||||
|
}
|
||||||
|
|
||||||
|
.svg-inline--fa.fa-swap-opacity .fa-primary {
|
||||||
|
opacity: var(--fa-secondary-opacity, 0.4);
|
||||||
|
}
|
||||||
|
|
||||||
|
.svg-inline--fa.fa-swap-opacity .fa-secondary {
|
||||||
|
opacity: var(--fa-primary-opacity, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
.svg-inline--fa mask .fa-primary,
|
||||||
|
.svg-inline--fa mask .fa-secondary {
|
||||||
|
fill: black;
|
||||||
|
}
|
||||||
|
|
||||||
|
.svg-inline--fa.fa-inverse {
|
||||||
|
fill: var(--fa-inverse, #fff);
|
||||||
|
}
|
||||||
|
|
||||||
|
.fa-stack {
|
||||||
|
display: inline-block;
|
||||||
|
height: 2em;
|
||||||
|
line-height: 2em;
|
||||||
|
position: relative;
|
||||||
|
vertical-align: middle;
|
||||||
|
width: 2.5em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.fa-inverse {
|
||||||
|
color: var(--fa-inverse, #fff);
|
||||||
|
}
|
||||||
|
|
||||||
|
.svg-inline--fa.fa-stack-1x {
|
||||||
|
--fa-width: 1.25em;
|
||||||
|
height: 1em;
|
||||||
|
width: var(--fa-width);
|
||||||
|
}
|
||||||
|
.svg-inline--fa.fa-stack-2x {
|
||||||
|
--fa-width: 2.5em;
|
||||||
|
height: 2em;
|
||||||
|
width: var(--fa-width);
|
||||||
|
}
|
||||||
|
|
||||||
|
.fa-stack-1x,
|
||||||
|
.fa-stack-2x {
|
||||||
|
inset: 0;
|
||||||
|
margin: auto;
|
||||||
|
position: absolute;
|
||||||
|
z-index: var(--fa-stack-z-index, auto);
|
||||||
|
}
|
||||||
6
src/fa/css/svg-with-js.min.css
vendored
Normal file
6
src/fa/css/svg-with-js.min.css
vendored
Normal file
File diff suppressed because one or more lines are too long
182
src/fa/css/svg.css
Normal file
182
src/fa/css/svg.css
Normal file
@@ -0,0 +1,182 @@
|
|||||||
|
/*!
|
||||||
|
* Font Awesome Free 7.1.0 by @fontawesome - https://fontawesome.com
|
||||||
|
* License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License)
|
||||||
|
* Copyright 2025 Fonticons, Inc.
|
||||||
|
*/
|
||||||
|
:root, :host {
|
||||||
|
--fa-font-solid: normal 900 1em/1 "Font Awesome 7 Free";
|
||||||
|
--fa-font-regular: normal 400 1em/1 "Font Awesome 7 Free";
|
||||||
|
--fa-font-light: normal 300 1em/1 "Font Awesome 7 Pro";
|
||||||
|
--fa-font-thin: normal 100 1em/1 "Font Awesome 7 Pro";
|
||||||
|
--fa-font-duotone: normal 900 1em/1 "Font Awesome 7 Duotone";
|
||||||
|
--fa-font-duotone-regular: normal 400 1em/1 "Font Awesome 7 Duotone";
|
||||||
|
--fa-font-duotone-light: normal 300 1em/1 "Font Awesome 7 Duotone";
|
||||||
|
--fa-font-duotone-thin: normal 100 1em/1 "Font Awesome 7 Duotone";
|
||||||
|
--fa-font-brands: normal 400 1em/1 "Font Awesome 7 Brands";
|
||||||
|
--fa-font-sharp-solid: normal 900 1em/1 "Font Awesome 7 Sharp";
|
||||||
|
--fa-font-sharp-regular: normal 400 1em/1 "Font Awesome 7 Sharp";
|
||||||
|
--fa-font-sharp-light: normal 300 1em/1 "Font Awesome 7 Sharp";
|
||||||
|
--fa-font-sharp-thin: normal 100 1em/1 "Font Awesome 7 Sharp";
|
||||||
|
--fa-font-sharp-duotone-solid: normal 900 1em/1 "Font Awesome 7 Sharp Duotone";
|
||||||
|
--fa-font-sharp-duotone-regular: normal 400 1em/1 "Font Awesome 7 Sharp Duotone";
|
||||||
|
--fa-font-sharp-duotone-light: normal 300 1em/1 "Font Awesome 7 Sharp Duotone";
|
||||||
|
--fa-font-sharp-duotone-thin: normal 100 1em/1 "Font Awesome 7 Sharp Duotone";
|
||||||
|
--fa-font-slab-regular: normal 400 1em/1 "Font Awesome 7 Slab";
|
||||||
|
--fa-font-slab-press-regular: normal 400 1em/1 "Font Awesome 7 Slab Press";
|
||||||
|
--fa-font-whiteboard-semibold: normal 600 1em/1 "Font Awesome 7 Whiteboard";
|
||||||
|
--fa-font-thumbprint-light: normal 300 1em/1 "Font Awesome 7 Thumbprint";
|
||||||
|
--fa-font-notdog-solid: normal 900 1em/1 "Font Awesome 7 Notdog";
|
||||||
|
--fa-font-notdog-duo-solid: normal 900 1em/1 "Font Awesome 7 Notdog Duo";
|
||||||
|
--fa-font-etch-solid: normal 900 1em/1 "Font Awesome 7 Etch";
|
||||||
|
--fa-font-jelly-regular: normal 400 1em/1 "Font Awesome 7 Jelly";
|
||||||
|
--fa-font-jelly-fill-regular: normal 400 1em/1 "Font Awesome 7 Jelly Fill";
|
||||||
|
--fa-font-jelly-duo-regular: normal 400 1em/1 "Font Awesome 7 Jelly Duo";
|
||||||
|
--fa-font-chisel-regular: normal 400 1em/1 "Font Awesome 7 Chisel";
|
||||||
|
--fa-font-utility-semibold: normal 600 1em/1 "Font Awesome 7 Utility";
|
||||||
|
--fa-font-utility-duo-semibold: normal 600 1em/1 "Font Awesome 7 Utility Duo";
|
||||||
|
--fa-font-utility-fill-semibold: normal 600 1em/1 "Font Awesome 7 Utility Fill";
|
||||||
|
}
|
||||||
|
|
||||||
|
.svg-inline--fa {
|
||||||
|
box-sizing: content-box;
|
||||||
|
display: var(--fa-display, inline-block);
|
||||||
|
height: 1em;
|
||||||
|
overflow: visible;
|
||||||
|
vertical-align: -0.125em;
|
||||||
|
width: var(--fa-width, 1.25em);
|
||||||
|
}
|
||||||
|
.svg-inline--fa.fa-2xs {
|
||||||
|
vertical-align: 0.1em;
|
||||||
|
}
|
||||||
|
.svg-inline--fa.fa-xs {
|
||||||
|
vertical-align: 0em;
|
||||||
|
}
|
||||||
|
.svg-inline--fa.fa-sm {
|
||||||
|
vertical-align: -0.0714285714em;
|
||||||
|
}
|
||||||
|
.svg-inline--fa.fa-lg {
|
||||||
|
vertical-align: -0.2em;
|
||||||
|
}
|
||||||
|
.svg-inline--fa.fa-xl {
|
||||||
|
vertical-align: -0.25em;
|
||||||
|
}
|
||||||
|
.svg-inline--fa.fa-2xl {
|
||||||
|
vertical-align: -0.3125em;
|
||||||
|
}
|
||||||
|
.svg-inline--fa.fa-li {
|
||||||
|
width: var(--fa-li-width, 2em);
|
||||||
|
inset-inline-start: calc(-1 * var(--fa-li-width, 2em));
|
||||||
|
inset-block-start: 0.25em; /* syncing vertical alignment with Web Font rendering */
|
||||||
|
}
|
||||||
|
|
||||||
|
.fa-layers-counter, .fa-layers-text {
|
||||||
|
display: inline-block;
|
||||||
|
position: absolute;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.fa-layers {
|
||||||
|
display: inline-block;
|
||||||
|
height: 1em;
|
||||||
|
position: relative;
|
||||||
|
text-align: center;
|
||||||
|
vertical-align: -0.125em;
|
||||||
|
width: var(--fa-width, 1.25em);
|
||||||
|
}
|
||||||
|
.fa-layers .svg-inline--fa {
|
||||||
|
inset: 0;
|
||||||
|
margin: auto;
|
||||||
|
position: absolute;
|
||||||
|
transform-origin: center center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.fa-layers-text {
|
||||||
|
left: 50%;
|
||||||
|
top: 50%;
|
||||||
|
transform: translate(-50%, -50%);
|
||||||
|
transform-origin: center center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.fa-layers-counter {
|
||||||
|
background-color: var(--fa-counter-background-color, #ff253a);
|
||||||
|
border-radius: var(--fa-counter-border-radius, 1em);
|
||||||
|
box-sizing: border-box;
|
||||||
|
color: var(--fa-inverse, #fff);
|
||||||
|
line-height: var(--fa-counter-line-height, 1);
|
||||||
|
max-width: var(--fa-counter-max-width, 5em);
|
||||||
|
min-width: var(--fa-counter-min-width, 1.5em);
|
||||||
|
overflow: hidden;
|
||||||
|
padding: var(--fa-counter-padding, 0.25em 0.5em);
|
||||||
|
right: var(--fa-right, 0);
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
top: var(--fa-top, 0);
|
||||||
|
transform: scale(var(--fa-counter-scale, 0.25));
|
||||||
|
transform-origin: top right;
|
||||||
|
}
|
||||||
|
|
||||||
|
.fa-layers-bottom-right {
|
||||||
|
bottom: var(--fa-bottom, 0);
|
||||||
|
right: var(--fa-right, 0);
|
||||||
|
top: auto;
|
||||||
|
transform: scale(var(--fa-layers-scale, 0.25));
|
||||||
|
transform-origin: bottom right;
|
||||||
|
}
|
||||||
|
|
||||||
|
.fa-layers-bottom-left {
|
||||||
|
bottom: var(--fa-bottom, 0);
|
||||||
|
left: var(--fa-left, 0);
|
||||||
|
right: auto;
|
||||||
|
top: auto;
|
||||||
|
transform: scale(var(--fa-layers-scale, 0.25));
|
||||||
|
transform-origin: bottom left;
|
||||||
|
}
|
||||||
|
|
||||||
|
.fa-layers-top-right {
|
||||||
|
top: var(--fa-top, 0);
|
||||||
|
right: var(--fa-right, 0);
|
||||||
|
transform: scale(var(--fa-layers-scale, 0.25));
|
||||||
|
transform-origin: top right;
|
||||||
|
}
|
||||||
|
|
||||||
|
.fa-layers-top-left {
|
||||||
|
left: var(--fa-left, 0);
|
||||||
|
right: auto;
|
||||||
|
top: var(--fa-top, 0);
|
||||||
|
transform: scale(var(--fa-layers-scale, 0.25));
|
||||||
|
transform-origin: top left;
|
||||||
|
}
|
||||||
|
|
||||||
|
.svg-inline--fa .fa-primary {
|
||||||
|
fill: var(--fa-primary-color, currentColor);
|
||||||
|
opacity: var(--fa-primary-opacity, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
.svg-inline--fa .fa-secondary {
|
||||||
|
fill: var(--fa-secondary-color, currentColor);
|
||||||
|
opacity: var(--fa-secondary-opacity, 0.4);
|
||||||
|
}
|
||||||
|
|
||||||
|
.svg-inline--fa.fa-swap-opacity .fa-primary {
|
||||||
|
opacity: var(--fa-secondary-opacity, 0.4);
|
||||||
|
}
|
||||||
|
|
||||||
|
.svg-inline--fa.fa-swap-opacity .fa-secondary {
|
||||||
|
opacity: var(--fa-primary-opacity, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
.svg-inline--fa mask .fa-primary,
|
||||||
|
.svg-inline--fa mask .fa-secondary {
|
||||||
|
fill: black;
|
||||||
|
}
|
||||||
|
|
||||||
|
.svg-inline--fa.fa-inverse {
|
||||||
|
fill: var(--fa-inverse, #fff);
|
||||||
|
}
|
||||||
|
|
||||||
|
.fa-stack-1x,
|
||||||
|
.fa-stack-2x {
|
||||||
|
inset: 0;
|
||||||
|
margin: auto;
|
||||||
|
position: absolute;
|
||||||
|
z-index: var(--fa-stack-z-index, auto);
|
||||||
|
}
|
||||||
6
src/fa/css/svg.min.css
vendored
Normal file
6
src/fa/css/svg.min.css
vendored
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
/*!
|
||||||
|
* Font Awesome Free 7.1.0 by @fontawesome - https://fontawesome.com
|
||||||
|
* License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License)
|
||||||
|
* Copyright 2025 Fonticons, Inc.
|
||||||
|
*/
|
||||||
|
:host,:root{--fa-font-solid:normal 900 1em/1 "Font Awesome 7 Free";--fa-font-regular:normal 400 1em/1 "Font Awesome 7 Free";--fa-font-light:normal 300 1em/1 "Font Awesome 7 Pro";--fa-font-thin:normal 100 1em/1 "Font Awesome 7 Pro";--fa-font-duotone:normal 900 1em/1 "Font Awesome 7 Duotone";--fa-font-duotone-regular:normal 400 1em/1 "Font Awesome 7 Duotone";--fa-font-duotone-light:normal 300 1em/1 "Font Awesome 7 Duotone";--fa-font-duotone-thin:normal 100 1em/1 "Font Awesome 7 Duotone";--fa-font-brands:normal 400 1em/1 "Font Awesome 7 Brands";--fa-font-sharp-solid:normal 900 1em/1 "Font Awesome 7 Sharp";--fa-font-sharp-regular:normal 400 1em/1 "Font Awesome 7 Sharp";--fa-font-sharp-light:normal 300 1em/1 "Font Awesome 7 Sharp";--fa-font-sharp-thin:normal 100 1em/1 "Font Awesome 7 Sharp";--fa-font-sharp-duotone-solid:normal 900 1em/1 "Font Awesome 7 Sharp Duotone";--fa-font-sharp-duotone-regular:normal 400 1em/1 "Font Awesome 7 Sharp Duotone";--fa-font-sharp-duotone-light:normal 300 1em/1 "Font Awesome 7 Sharp Duotone";--fa-font-sharp-duotone-thin:normal 100 1em/1 "Font Awesome 7 Sharp Duotone";--fa-font-slab-regular:normal 400 1em/1 "Font Awesome 7 Slab";--fa-font-slab-press-regular:normal 400 1em/1 "Font Awesome 7 Slab Press";--fa-font-whiteboard-semibold:normal 600 1em/1 "Font Awesome 7 Whiteboard";--fa-font-thumbprint-light:normal 300 1em/1 "Font Awesome 7 Thumbprint";--fa-font-notdog-solid:normal 900 1em/1 "Font Awesome 7 Notdog";--fa-font-notdog-duo-solid:normal 900 1em/1 "Font Awesome 7 Notdog Duo";--fa-font-etch-solid:normal 900 1em/1 "Font Awesome 7 Etch";--fa-font-jelly-regular:normal 400 1em/1 "Font Awesome 7 Jelly";--fa-font-jelly-fill-regular:normal 400 1em/1 "Font Awesome 7 Jelly Fill";--fa-font-jelly-duo-regular:normal 400 1em/1 "Font Awesome 7 Jelly Duo";--fa-font-chisel-regular:normal 400 1em/1 "Font Awesome 7 Chisel";--fa-font-utility-semibold:normal 600 1em/1 "Font Awesome 7 Utility";--fa-font-utility-duo-semibold:normal 600 1em/1 "Font Awesome 7 Utility Duo";--fa-font-utility-fill-semibold:normal 600 1em/1 "Font Awesome 7 Utility Fill"}.svg-inline--fa{box-sizing:content-box;display:var(--fa-display,inline-block);height:1em;overflow:visible;vertical-align:-.125em;width:var(--fa-width,1.25em)}.svg-inline--fa.fa-2xs{vertical-align:.1em}.svg-inline--fa.fa-xs{vertical-align:0}.svg-inline--fa.fa-sm{vertical-align:-.0714285714em}.svg-inline--fa.fa-lg{vertical-align:-.2em}.svg-inline--fa.fa-xl{vertical-align:-.25em}.svg-inline--fa.fa-2xl{vertical-align:-.3125em}.svg-inline--fa.fa-li{width:var(--fa-li-width,2em);inset-inline-start:calc(var(--fa-li-width, 2em)*-1);inset-block-start:.25em}.fa-layers-counter,.fa-layers-text{display:inline-block;position:absolute;text-align:center}.fa-layers{display:inline-block;height:1em;position:relative;text-align:center;vertical-align:-.125em;width:var(--fa-width,1.25em)}.fa-layers .svg-inline--fa{inset:0;margin:auto;position:absolute;transform-origin:center center}.fa-layers-text{left:50%;top:50%;transform:translate(-50%,-50%);transform-origin:center center}.fa-layers-counter{background-color:var(--fa-counter-background-color,#ff253a);border-radius:var(--fa-counter-border-radius,1em);box-sizing:border-box;color:var(--fa-inverse,#fff);line-height:var(--fa-counter-line-height,1);max-width:var(--fa-counter-max-width,5em);min-width:var(--fa-counter-min-width,1.5em);overflow:hidden;padding:var(--fa-counter-padding,.25em .5em);right:var(--fa-right,0);text-overflow:ellipsis;top:var(--fa-top,0);transform:scale(var(--fa-counter-scale,.25));transform-origin:top right}.fa-layers-bottom-right{bottom:var(--fa-bottom,0);right:var(--fa-right,0);top:auto;transform:scale(var(--fa-layers-scale,.25));transform-origin:bottom right}.fa-layers-bottom-left{bottom:var(--fa-bottom,0);left:var(--fa-left,0);right:auto;top:auto;transform:scale(var(--fa-layers-scale,.25));transform-origin:bottom left}.fa-layers-top-right{top:var(--fa-top,0);right:var(--fa-right,0);transform:scale(var(--fa-layers-scale,.25));transform-origin:top right}.fa-layers-top-left{left:var(--fa-left,0);right:auto;top:var(--fa-top,0);transform:scale(var(--fa-layers-scale,.25));transform-origin:top left}.svg-inline--fa .fa-primary{fill:var(--fa-primary-color,currentColor);opacity:var(--fa-primary-opacity,1)}.svg-inline--fa .fa-secondary{fill:var(--fa-secondary-color,currentColor)}.svg-inline--fa .fa-secondary,.svg-inline--fa.fa-swap-opacity .fa-primary{opacity:var(--fa-secondary-opacity,.4)}.svg-inline--fa.fa-swap-opacity .fa-secondary{opacity:var(--fa-primary-opacity,1)}.svg-inline--fa mask .fa-primary,.svg-inline--fa mask .fa-secondary{fill:#000}.svg-inline--fa.fa-inverse{fill:var(--fa-inverse,#fff)}.fa-stack-1x,.fa-stack-2x{inset:0;margin:auto;position:absolute;z-index:var(--fa-stack-z-index,auto)}
|
||||||
27
src/fa/css/v4-font-face.css
Normal file
27
src/fa/css/v4-font-face.css
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
/*!
|
||||||
|
* Font Awesome Free 7.1.0 by @fontawesome - https://fontawesome.com
|
||||||
|
* License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License)
|
||||||
|
* Copyright 2025 Fonticons, Inc.
|
||||||
|
*/
|
||||||
|
@font-face {
|
||||||
|
font-family: "FontAwesome";
|
||||||
|
font-display: block;
|
||||||
|
src: url("../webfonts/fa-solid-900.woff2") format("woff2");
|
||||||
|
}
|
||||||
|
@font-face {
|
||||||
|
font-family: "FontAwesome";
|
||||||
|
font-display: block;
|
||||||
|
src: url("../webfonts/fa-brands-400.woff2") format("woff2");
|
||||||
|
}
|
||||||
|
@font-face {
|
||||||
|
font-family: "FontAwesome";
|
||||||
|
font-display: block;
|
||||||
|
src: url("../webfonts/fa-regular-400.woff2") format("woff2");
|
||||||
|
unicode-range: U+F003, U+F006, U+F014, U+F016-F017, U+F01A-F01B, U+F01D, U+F022, U+F03E, U+F044, U+F046, U+F05C-F05D, U+F06E, U+F070, U+F087-F088, U+F08A, U+F094, U+F096-F097, U+F09D, U+F0A0, U+F0A2, U+F0A4-F0A7, U+F0C5, U+F0C7, U+F0E5-F0E6, U+F0EB, U+F0F6-F0F8, U+F10C, U+F114-F115, U+F118-F11A, U+F11C-F11D, U+F133, U+F147, U+F14E, U+F150-F152, U+F185-F186, U+F18E, U+F190-F192, U+F196, U+F1C1-F1C9, U+F1D9, U+F1DB, U+F1E3, U+F1EA, U+F1F7, U+F1F9, U+F20A, U+F247-F248, U+F24A, U+F24D, U+F255-F25B, U+F25D, U+F271-F274, U+F278, U+F27B, U+F28C, U+F28E, U+F29C, U+F2B5, U+F2B7, U+F2BA, U+F2BC, U+F2BE, U+F2C0-F2C1, U+F2C3, U+F2D0, U+F2D2, U+F2D4, U+F2DC;
|
||||||
|
}
|
||||||
|
@font-face {
|
||||||
|
font-family: "FontAwesome";
|
||||||
|
font-display: block;
|
||||||
|
src: url("../webfonts/fa-v4compatibility.woff2") format("woff2");
|
||||||
|
unicode-range: U+F041, U+F047, U+F065-F066, U+F07D-F07E, U+F080, U+F08B, U+F08E, U+F090, U+F09A, U+F0AC, U+F0AE, U+F0B2, U+F0D0, U+F0D6, U+F0E4, U+F0EC, U+F10A-F10B, U+F123, U+F13E, U+F148-F149, U+F14C, U+F156, U+F15E, U+F160-F161, U+F163, U+F175-F178, U+F195, U+F1F8, U+F219, U+F27A;
|
||||||
|
}
|
||||||
6
src/fa/css/v4-font-face.min.css
vendored
Normal file
6
src/fa/css/v4-font-face.min.css
vendored
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
/*!
|
||||||
|
* Font Awesome Free 7.1.0 by @fontawesome - https://fontawesome.com
|
||||||
|
* License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License)
|
||||||
|
* Copyright 2025 Fonticons, Inc.
|
||||||
|
*/
|
||||||
|
@font-face{font-family:"FontAwesome";font-display:block;src:url(../webfonts/fa-solid-900.woff2) format("woff2")}@font-face{font-family:"FontAwesome";font-display:block;src:url(../webfonts/fa-brands-400.woff2) format("woff2")}@font-face{font-family:"FontAwesome";font-display:block;src:url(../webfonts/fa-regular-400.woff2) format("woff2");unicode-range:u+f003,u+f006,u+f014,u+f016-f017,u+f01a-f01b,u+f01d,u+f022,u+f03e,u+f044,u+f046,u+f05c-f05d,u+f06e,u+f070,u+f087-f088,u+f08a,u+f094,u+f096-f097,u+f09d,u+f0a0,u+f0a2,u+f0a4-f0a7,u+f0c5,u+f0c7,u+f0e5-f0e6,u+f0eb,u+f0f6-f0f8,u+f10c,u+f114-f115,u+f118-f11a,u+f11c-f11d,u+f133,u+f147,u+f14e,u+f150-f152,u+f185-f186,u+f18e,u+f190-f192,u+f196,u+f1c1-f1c9,u+f1d9,u+f1db,u+f1e3,u+f1ea,u+f1f7,u+f1f9,u+f20a,u+f247-f248,u+f24a,u+f24d,u+f255-f25b,u+f25d,u+f271-f274,u+f278,u+f27b,u+f28c,u+f28e,u+f29c,u+f2b5,u+f2b7,u+f2ba,u+f2bc,u+f2be,u+f2c0-f2c1,u+f2c3,u+f2d0,u+f2d2,u+f2d4,u+f2dc}@font-face{font-family:"FontAwesome";font-display:block;src:url(../webfonts/fa-v4compatibility.woff2) format("woff2");unicode-range:u+f041,u+f047,u+f065-f066,u+f07d-f07e,u+f080,u+f08b,u+f08e,u+f090,u+f09a,u+f0ac,u+f0ae,u+f0b2,u+f0d0,u+f0d6,u+f0e4,u+f0ec,u+f10a-f10b,u+f123,u+f13e,u+f148-f149,u+f14c,u+f156,u+f15e,u+f160-f161,u+f163,u+f175-f178,u+f195,u+f1f8,u+f219,u+f27a}
|
||||||
2818
src/fa/css/v4-shims.css
Normal file
2818
src/fa/css/v4-shims.css
Normal file
File diff suppressed because it is too large
Load Diff
6
src/fa/css/v4-shims.min.css
vendored
Normal file
6
src/fa/css/v4-shims.min.css
vendored
Normal file
File diff suppressed because one or more lines are too long
23
src/fa/css/v5-font-face.css
Normal file
23
src/fa/css/v5-font-face.css
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
/*!
|
||||||
|
* Font Awesome Free 7.1.0 by @fontawesome - https://fontawesome.com
|
||||||
|
* License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License)
|
||||||
|
* Copyright 2025 Fonticons, Inc.
|
||||||
|
*/
|
||||||
|
@font-face {
|
||||||
|
font-family: "Font Awesome 5 Brands";
|
||||||
|
font-display: block;
|
||||||
|
font-weight: 400;
|
||||||
|
src: url("../webfonts/fa-brands-400.woff2") format("woff2");
|
||||||
|
}
|
||||||
|
@font-face {
|
||||||
|
font-family: "Font Awesome 5 Free";
|
||||||
|
font-display: block;
|
||||||
|
font-weight: 900;
|
||||||
|
src: url("../webfonts/fa-solid-900.woff2") format("woff2");
|
||||||
|
}
|
||||||
|
@font-face {
|
||||||
|
font-family: "Font Awesome 5 Free";
|
||||||
|
font-display: block;
|
||||||
|
font-weight: 400;
|
||||||
|
src: url("../webfonts/fa-regular-400.woff2") format("woff2");
|
||||||
|
}
|
||||||
6
src/fa/css/v5-font-face.min.css
vendored
Normal file
6
src/fa/css/v5-font-face.min.css
vendored
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
/*!
|
||||||
|
* Font Awesome Free 7.1.0 by @fontawesome - https://fontawesome.com
|
||||||
|
* License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License)
|
||||||
|
* Copyright 2025 Fonticons, Inc.
|
||||||
|
*/
|
||||||
|
@font-face{font-family:"Font Awesome 5 Brands";font-display:block;font-weight:400;src:url(../webfonts/fa-brands-400.woff2) format("woff2")}@font-face{font-family:"Font Awesome 5 Free";font-display:block;font-weight:900;src:url(../webfonts/fa-solid-900.woff2) format("woff2")}@font-face{font-family:"Font Awesome 5 Free";font-display:block;font-weight:400;src:url(../webfonts/fa-regular-400.woff2) format("woff2")}
|
||||||
BIN
src/fa/webfonts/fa-brands-400.woff2
Normal file
BIN
src/fa/webfonts/fa-brands-400.woff2
Normal file
Binary file not shown.
BIN
src/fa/webfonts/fa-regular-400.woff2
Normal file
BIN
src/fa/webfonts/fa-regular-400.woff2
Normal file
Binary file not shown.
BIN
src/fa/webfonts/fa-solid-900.woff2
Normal file
BIN
src/fa/webfonts/fa-solid-900.woff2
Normal file
Binary file not shown.
BIN
src/fa/webfonts/fa-v4compatibility.woff2
Normal file
BIN
src/fa/webfonts/fa-v4compatibility.woff2
Normal file
Binary file not shown.
Reference in New Issue
Block a user