mirror of
https://github.com/praktimarc/kst4contest.git
synced 2026-07-14 00:26:52 +02:00
Compare commits
8 Commits
098dd31b58
...
v1.41.1
| Author | SHA1 | Date | |
|---|---|---|---|
|
4a34e28a84
|
|||
|
38ef50cee8
|
|||
| d45a637d00 | |||
| 1ec2b1a450 | |||
| 19e8cff6b6 | |||
|
62999cfed8
|
|||
|
49524146e8
|
|||
|
dd2ac3bc69
|
@@ -4,8 +4,12 @@ on:
|
|||||||
push:
|
push:
|
||||||
branches:
|
branches:
|
||||||
- main
|
- main
|
||||||
schedule:
|
paths:
|
||||||
- cron: "20 2 * * *"
|
- "src/**"
|
||||||
|
- "pom.xml"
|
||||||
|
- "mvnw"
|
||||||
|
- "mvnw.cmd"
|
||||||
|
- ".github/workflows/nightly-artifacts.yml"
|
||||||
workflow_dispatch:
|
workflow_dispatch:
|
||||||
|
|
||||||
env:
|
env:
|
||||||
|
|||||||
@@ -35,3 +35,6 @@ dist/
|
|||||||
|
|
||||||
#zip files for local backups
|
#zip files for local backups
|
||||||
*.zip
|
*.zip
|
||||||
|
|
||||||
|
# node Modules in website
|
||||||
|
website/node_modules/
|
||||||
|
|||||||
@@ -1,6 +1,10 @@
|
|||||||
# KST4Contest
|
# KST4Contest
|
||||||
|
|
||||||
KST4Contest (also known as pratiKST) is a Java-based chat client for ON4KST, focused on VHF/UHF/SHF contest operation.
|
KST4Contest (also known as pratiKST) is a Java-based chat client for [ON4KST](http://www.on4kst.com/chat), focused on VHF/UHF/SHF contest operation.
|
||||||
|
|
||||||
|
## Website
|
||||||
|
|
||||||
|
The offical Website of KST4Contest is now instead of [do5amf.funkerportal.de](https://do5amf.funkerportal.de) the new website [here](https://kst4contest.hamradioonline.de) [https://kst4contest.hamradioonline.de](https://kst4contest.hamradioonline.de)
|
||||||
|
|
||||||
## Documentation
|
## Documentation
|
||||||
|
|
||||||
|
|||||||
@@ -6,7 +6,7 @@
|
|||||||
|
|
||||||
<groupId>de.x08</groupId>
|
<groupId>de.x08</groupId>
|
||||||
<artifactId>praktiKST</artifactId>
|
<artifactId>praktiKST</artifactId>
|
||||||
<version>1.42.0-nightly</version>
|
<version>1.41.1-nightly</version>
|
||||||
|
|
||||||
<name>praktiKST</name>
|
<name>praktiKST</name>
|
||||||
|
|
||||||
|
|||||||
@@ -20,7 +20,7 @@ public class ApplicationConstants {
|
|||||||
/**
|
/**
|
||||||
* Name of file to store preferences in.
|
* Name of file to store preferences in.
|
||||||
*/
|
*/
|
||||||
public static final double APPLICATION_CURRENTVERSIONNUMBER = 1.42;
|
public static final double APPLICATION_CURRENTVERSIONNUMBER = 1.411;
|
||||||
|
|
||||||
public static final String VERSIONINFOURLFORUPDATES_KST4CONTEST = "https://do5amf.funkerportal.de/kst4ContestVersionInfo.xml";
|
public static final String VERSIONINFOURLFORUPDATES_KST4CONTEST = "https://do5amf.funkerportal.de/kst4ContestVersionInfo.xml";
|
||||||
public static final String VERSIONINFDOWNLOADEDLOCALFILE = "kst4ContestVersionInfo.xml";
|
public static final String VERSIONINFDOWNLOADEDLOCALFILE = "kst4ContestVersionInfo.xml";
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -17,7 +17,7 @@
|
|||||||
<meta name="twitter:title" content="About KST4Contest">
|
<meta name="twitter:title" content="About KST4Contest">
|
||||||
<meta name="twitter:description" content="About KST4Contest and its contest-oriented ON4KST workflow.">
|
<meta name="twitter:description" content="About KST4Contest and its contest-oriented ON4KST workflow.">
|
||||||
|
|
||||||
<link rel="stylesheet" href="/assets/css/main.css?v=1783381592602">
|
<link rel="stylesheet" href="/assets/css/main.css?v=1783425387839">
|
||||||
<link rel="alternate" type="application/rss+xml" title="KST4Contest News" href="/feed.xml">
|
<link rel="alternate" type="application/rss+xml" title="KST4Contest News" href="/feed.xml">
|
||||||
|
|
||||||
<meta property="og:image" content="https://kst4contest.hamradioonline.de/assets/social/kst4contest-og.png">
|
<meta property="og:image" content="https://kst4contest.hamradioonline.de/assets/social/kst4contest-og.png">
|
||||||
@@ -57,7 +57,7 @@
|
|||||||
|
|
||||||
<a href="/faq/">FAQ</a>
|
<a href="/faq/">FAQ</a>
|
||||||
|
|
||||||
<a class="nav-cta" href="https://github.com/praktimarc/kst4contest/releases/latest">Download</a>
|
<a class="nav-cta" href="/download/">Download</a>
|
||||||
</nav>
|
</nav>
|
||||||
</header>
|
</header>
|
||||||
|
|
||||||
|
|||||||
@@ -17,7 +17,7 @@
|
|||||||
<meta name="twitter:title" content="Contact | KST4Contest">
|
<meta name="twitter:title" content="Contact | KST4Contest">
|
||||||
<meta name="twitter:description" content="Contact options for KST4Contest.">
|
<meta name="twitter:description" content="Contact options for KST4Contest.">
|
||||||
|
|
||||||
<link rel="stylesheet" href="/assets/css/main.css?v=1783381592602">
|
<link rel="stylesheet" href="/assets/css/main.css?v=1783425387839">
|
||||||
<link rel="alternate" type="application/rss+xml" title="KST4Contest News" href="/feed.xml">
|
<link rel="alternate" type="application/rss+xml" title="KST4Contest News" href="/feed.xml">
|
||||||
|
|
||||||
<meta property="og:image" content="https://kst4contest.hamradioonline.de/assets/social/kst4contest-og.png">
|
<meta property="og:image" content="https://kst4contest.hamradioonline.de/assets/social/kst4contest-og.png">
|
||||||
@@ -57,7 +57,7 @@
|
|||||||
|
|
||||||
<a href="/faq/">FAQ</a>
|
<a href="/faq/">FAQ</a>
|
||||||
|
|
||||||
<a class="nav-cta" href="https://github.com/praktimarc/kst4contest/releases/latest">Download</a>
|
<a class="nav-cta" href="/download/">Download</a>
|
||||||
</nav>
|
</nav>
|
||||||
</header>
|
</header>
|
||||||
|
|
||||||
|
|||||||
@@ -17,7 +17,7 @@
|
|||||||
<meta name="twitter:title" content="Download KST4Contest">
|
<meta name="twitter:title" content="Download KST4Contest">
|
||||||
<meta name="twitter:description" content="Download KST4Contest releases for Windows, Linux and macOS.">
|
<meta name="twitter:description" content="Download KST4Contest releases for Windows, Linux and macOS.">
|
||||||
|
|
||||||
<link rel="stylesheet" href="/assets/css/main.css?v=1783381592602">
|
<link rel="stylesheet" href="/assets/css/main.css?v=1783425387839">
|
||||||
<link rel="alternate" type="application/rss+xml" title="KST4Contest News" href="/feed.xml">
|
<link rel="alternate" type="application/rss+xml" title="KST4Contest News" href="/feed.xml">
|
||||||
|
|
||||||
<meta property="og:image" content="https://kst4contest.hamradioonline.de/assets/social/kst4contest-og.png">
|
<meta property="og:image" content="https://kst4contest.hamradioonline.de/assets/social/kst4contest-og.png">
|
||||||
@@ -57,7 +57,7 @@
|
|||||||
|
|
||||||
<a href="/faq/">FAQ</a>
|
<a href="/faq/">FAQ</a>
|
||||||
|
|
||||||
<a class="nav-cta" href="https://github.com/praktimarc/kst4contest/releases/latest">Download</a>
|
<a class="nav-cta" href="/download/">Download</a>
|
||||||
</nav>
|
</nav>
|
||||||
</header>
|
</header>
|
||||||
|
|
||||||
@@ -105,6 +105,18 @@
|
|||||||
<p class="badge">Recommended</p>
|
<p class="badge">Recommended</p>
|
||||||
|
|
||||||
|
|
||||||
|
<h3>Linux</h3>
|
||||||
|
<p><strong>Flatpak (.flatpakref)</strong></p>
|
||||||
|
<p>Recommended for most Linux users. Open the file with GNOME Software / Discover, or run: flatpak install de.x08.KST4Contest.flatpakref</p>
|
||||||
|
|
||||||
|
<a class="button secondary" href="https://github.com/praktimarc/kst4contest/releases/download/v1.41.0/de.x08.KST4Contest.flatpakref">Download →</a>
|
||||||
|
</article>
|
||||||
|
|
||||||
|
<article class="card download-card">
|
||||||
|
<div class="feature-icon">🐧</div>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<h3>Linux</h3>
|
<h3>Linux</h3>
|
||||||
<p><strong>AppImage x86_64</strong></p>
|
<p><strong>AppImage x86_64</strong></p>
|
||||||
<p>Portable Linux build without package installation.</p>
|
<p>Portable Linux build without package installation.</p>
|
||||||
@@ -204,8 +216,9 @@
|
|||||||
<p class="eyebrow">Not sure?</p>
|
<p class="eyebrow">Not sure?</p>
|
||||||
<h2>Which file should I use?</h2>
|
<h2>Which file should I use?</h2>
|
||||||
<p>
|
<p>
|
||||||
Windows users usually want the ZIP package. Linux users can start with the AppImage,
|
Windows users usually want the ZIP package. Linux users are best served by the Flatpak,
|
||||||
or install a native DEB/RPM package if preferred. The PDF manuals are attached to the same GitHub release.
|
which auto-updates and works across distributions; the AppImage or a native DEB/RPM/Arch
|
||||||
|
package are alternatives if preferred. The PDF manuals are attached to the same GitHub release.
|
||||||
</p>
|
</p>
|
||||||
<div class="actions">
|
<div class="actions">
|
||||||
<a class="button" href="/manual/en/installation/">Installation guide</a>
|
<a class="button" href="/manual/en/installation/">Installation guide</a>
|
||||||
|
|||||||
@@ -17,7 +17,7 @@
|
|||||||
<meta name="twitter:title" content="KST4Contest FAQ">
|
<meta name="twitter:title" content="KST4Contest FAQ">
|
||||||
<meta name="twitter:description" content="Frequently asked questions about KST4Contest, ON4KST contest operation, AirScout integration and VHF/UHF/SHF contest workflow.">
|
<meta name="twitter:description" content="Frequently asked questions about KST4Contest, ON4KST contest operation, AirScout integration and VHF/UHF/SHF contest workflow.">
|
||||||
|
|
||||||
<link rel="stylesheet" href="/assets/css/main.css?v=1783381592602">
|
<link rel="stylesheet" href="/assets/css/main.css?v=1783425387839">
|
||||||
<link rel="alternate" type="application/rss+xml" title="KST4Contest News" href="/feed.xml">
|
<link rel="alternate" type="application/rss+xml" title="KST4Contest News" href="/feed.xml">
|
||||||
|
|
||||||
<meta property="og:image" content="https://kst4contest.hamradioonline.de/assets/social/kst4contest-og.png">
|
<meta property="og:image" content="https://kst4contest.hamradioonline.de/assets/social/kst4contest-og.png">
|
||||||
@@ -57,7 +57,7 @@
|
|||||||
|
|
||||||
<a href="/faq/">FAQ</a>
|
<a href="/faq/">FAQ</a>
|
||||||
|
|
||||||
<a class="nav-cta" href="https://github.com/praktimarc/kst4contest/releases/latest">Download</a>
|
<a class="nav-cta" href="/download/">Download</a>
|
||||||
</nav>
|
</nav>
|
||||||
</header>
|
</header>
|
||||||
|
|
||||||
|
|||||||
@@ -17,7 +17,7 @@
|
|||||||
<meta name="twitter:title" content="AirScout Integration">
|
<meta name="twitter:title" content="AirScout Integration">
|
||||||
<meta name="twitter:description" content="AirScout information helps operators evaluate AP windows, aircraft scatter timing and candidate stations during VHF/UHF/SHF contests.">
|
<meta name="twitter:description" content="AirScout information helps operators evaluate AP windows, aircraft scatter timing and candidate stations during VHF/UHF/SHF contests.">
|
||||||
|
|
||||||
<link rel="stylesheet" href="/assets/css/main.css?v=1783381592602">
|
<link rel="stylesheet" href="/assets/css/main.css?v=1783425387839">
|
||||||
<link rel="alternate" type="application/rss+xml" title="KST4Contest News" href="/feed.xml">
|
<link rel="alternate" type="application/rss+xml" title="KST4Contest News" href="/feed.xml">
|
||||||
|
|
||||||
<meta property="og:image" content="https://kst4contest.hamradioonline.de/assets/social/kst4contest-og.png">
|
<meta property="og:image" content="https://kst4contest.hamradioonline.de/assets/social/kst4contest-og.png">
|
||||||
@@ -57,7 +57,7 @@
|
|||||||
|
|
||||||
<a href="/faq/">FAQ</a>
|
<a href="/faq/">FAQ</a>
|
||||||
|
|
||||||
<a class="nav-cta" href="https://github.com/praktimarc/kst4contest/releases/latest">Download</a>
|
<a class="nav-cta" href="/download/">Download</a>
|
||||||
</nav>
|
</nav>
|
||||||
</header>
|
</header>
|
||||||
|
|
||||||
@@ -107,6 +107,16 @@
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<a class="button secondary" href="/features/timeline/">Timeline View</a>
|
<a class="button secondary" href="/features/timeline/">Timeline View</a>
|
||||||
|
|
||||||
|
|
||||||
@@ -144,10 +154,6 @@
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -159,12 +165,6 @@
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</article>
|
</article>
|
||||||
|
|||||||
@@ -17,7 +17,7 @@
|
|||||||
<meta name="twitter:title" content="Dual Chat Categories">
|
<meta name="twitter:title" content="Dual Chat Categories">
|
||||||
<meta name="twitter:description" content="Dual category support gives contest operators better overview when working across multiple ON4KST chat rooms.">
|
<meta name="twitter:description" content="Dual category support gives contest operators better overview when working across multiple ON4KST chat rooms.">
|
||||||
|
|
||||||
<link rel="stylesheet" href="/assets/css/main.css?v=1783381592602">
|
<link rel="stylesheet" href="/assets/css/main.css?v=1783425387839">
|
||||||
<link rel="alternate" type="application/rss+xml" title="KST4Contest News" href="/feed.xml">
|
<link rel="alternate" type="application/rss+xml" title="KST4Contest News" href="/feed.xml">
|
||||||
|
|
||||||
<meta property="og:image" content="https://kst4contest.hamradioonline.de/assets/social/kst4contest-og.png">
|
<meta property="og:image" content="https://kst4contest.hamradioonline.de/assets/social/kst4contest-og.png">
|
||||||
@@ -57,7 +57,7 @@
|
|||||||
|
|
||||||
<a href="/faq/">FAQ</a>
|
<a href="/faq/">FAQ</a>
|
||||||
|
|
||||||
<a class="nav-cta" href="https://github.com/praktimarc/kst4contest/releases/latest">Download</a>
|
<a class="nav-cta" href="/download/">Download</a>
|
||||||
</nav>
|
</nav>
|
||||||
</header>
|
</header>
|
||||||
|
|
||||||
@@ -101,6 +101,16 @@
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<a class="button secondary" href="/features/priority-score/">Priority Score System</a>
|
<a class="button secondary" href="/features/priority-score/">Priority Score System</a>
|
||||||
|
|
||||||
|
|
||||||
@@ -110,18 +120,6 @@
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -141,6 +139,8 @@
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</article>
|
</article>
|
||||||
|
|||||||
@@ -17,7 +17,7 @@
|
|||||||
<meta name="twitter:title" content="DXCluster Server">
|
<meta name="twitter:title" content="DXCluster Server">
|
||||||
<meta name="twitter:description" content="KST4Contest includes DXCluster functionality to support situational awareness during contest operation.">
|
<meta name="twitter:description" content="KST4Contest includes DXCluster functionality to support situational awareness during contest operation.">
|
||||||
|
|
||||||
<link rel="stylesheet" href="/assets/css/main.css?v=1783381592602">
|
<link rel="stylesheet" href="/assets/css/main.css?v=1783425387839">
|
||||||
<link rel="alternate" type="application/rss+xml" title="KST4Contest News" href="/feed.xml">
|
<link rel="alternate" type="application/rss+xml" title="KST4Contest News" href="/feed.xml">
|
||||||
|
|
||||||
<meta property="og:image" content="https://kst4contest.hamradioonline.de/assets/social/kst4contest-og.png">
|
<meta property="og:image" content="https://kst4contest.hamradioonline.de/assets/social/kst4contest-og.png">
|
||||||
@@ -57,7 +57,7 @@
|
|||||||
|
|
||||||
<a href="/faq/">FAQ</a>
|
<a href="/faq/">FAQ</a>
|
||||||
|
|
||||||
<a class="nav-cta" href="https://github.com/praktimarc/kst4contest/releases/latest">Download</a>
|
<a class="nav-cta" href="/download/">Download</a>
|
||||||
</nav>
|
</nav>
|
||||||
</header>
|
</header>
|
||||||
|
|
||||||
@@ -106,13 +106,23 @@
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<a class="button secondary" href="/features/log-sync/">Log Synchronization</a>
|
<a class="button secondary" href="/features/log-sync/">Log Synchronization</a>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -130,16 +140,6 @@
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</article>
|
</article>
|
||||||
|
|||||||
@@ -17,7 +17,7 @@
|
|||||||
<meta name="twitter:title" content="KST4Contest Features">
|
<meta name="twitter:title" content="KST4Contest Features">
|
||||||
<meta name="twitter:description" content="Contest-optimized ON4KST features for VHF, UHF and SHF operation.">
|
<meta name="twitter:description" content="Contest-optimized ON4KST features for VHF, UHF and SHF operation.">
|
||||||
|
|
||||||
<link rel="stylesheet" href="/assets/css/main.css?v=1783381592602">
|
<link rel="stylesheet" href="/assets/css/main.css?v=1783425387839">
|
||||||
<link rel="alternate" type="application/rss+xml" title="KST4Contest News" href="/feed.xml">
|
<link rel="alternate" type="application/rss+xml" title="KST4Contest News" href="/feed.xml">
|
||||||
|
|
||||||
<meta property="og:image" content="https://kst4contest.hamradioonline.de/assets/social/kst4contest-og.png">
|
<meta property="og:image" content="https://kst4contest.hamradioonline.de/assets/social/kst4contest-og.png">
|
||||||
@@ -57,7 +57,7 @@
|
|||||||
|
|
||||||
<a href="/faq/">FAQ</a>
|
<a href="/faq/">FAQ</a>
|
||||||
|
|
||||||
<a class="nav-cta" href="https://github.com/praktimarc/kst4contest/releases/latest">Download</a>
|
<a class="nav-cta" href="/download/">Download</a>
|
||||||
</nav>
|
</nav>
|
||||||
</header>
|
</header>
|
||||||
|
|
||||||
@@ -75,22 +75,6 @@
|
|||||||
<section class="section">
|
<section class="section">
|
||||||
<div class="grid">
|
<div class="grid">
|
||||||
|
|
||||||
<article class="card feature-card">
|
|
||||||
<div class="feature-icon"></div>
|
|
||||||
<p class="eyebrow"></p>
|
|
||||||
<h3><a href="/features/">KST4Contest Features</a></h3>
|
|
||||||
<p></p>
|
|
||||||
<a href="/features/">Learn more →</a>
|
|
||||||
</article>
|
|
||||||
|
|
||||||
<article class="card feature-card">
|
|
||||||
<div class="feature-icon">🎯</div>
|
|
||||||
<p class="eyebrow">Contest Workflow</p>
|
|
||||||
<h3><a href="/features/priority-score/">Priority Score System</a></h3>
|
|
||||||
<p>Find the most promising stations faster using contest-aware candidate scoring.</p>
|
|
||||||
<a href="/features/priority-score/">Learn more →</a>
|
|
||||||
</article>
|
|
||||||
|
|
||||||
<article class="card feature-card">
|
<article class="card feature-card">
|
||||||
<div class="feature-icon">✈️</div>
|
<div class="feature-icon">✈️</div>
|
||||||
<p class="eyebrow">Aircraft Scatter</p>
|
<p class="eyebrow">Aircraft Scatter</p>
|
||||||
@@ -99,30 +83,6 @@
|
|||||||
<a href="/features/airscout/">Learn more →</a>
|
<a href="/features/airscout/">Learn more →</a>
|
||||||
</article>
|
</article>
|
||||||
|
|
||||||
<article class="card feature-card">
|
|
||||||
<div class="feature-icon">⏱️</div>
|
|
||||||
<p class="eyebrow">Contest Awareness</p>
|
|
||||||
<h3><a href="/features/timeline/">Timeline View</a></h3>
|
|
||||||
<p>See upcoming AP windows and candidate timing in a compact contest timeline.</p>
|
|
||||||
<a href="/features/timeline/">Learn more →</a>
|
|
||||||
</article>
|
|
||||||
|
|
||||||
<article class="card feature-card">
|
|
||||||
<div class="feature-icon">🔔</div>
|
|
||||||
<p class="eyebrow">Sked Management</p>
|
|
||||||
<h3><a href="/features/sked-reminder/">Sked Reminder</a></h3>
|
|
||||||
<p>Keep scheduled contacts visible and avoid missing time-critical skeds.</p>
|
|
||||||
<a href="/features/sked-reminder/">Learn more →</a>
|
|
||||||
</article>
|
|
||||||
|
|
||||||
<article class="card feature-card">
|
|
||||||
<div class="feature-icon">🔄</div>
|
|
||||||
<p class="eyebrow">Logger Integration</p>
|
|
||||||
<h3><a href="/features/log-sync/">Log Synchronization</a></h3>
|
|
||||||
<p>Connect ON4KST chat workflow with Win-Test, UCXLog and contest logging state.</p>
|
|
||||||
<a href="/features/log-sync/">Learn more →</a>
|
|
||||||
</article>
|
|
||||||
|
|
||||||
<article class="card feature-card">
|
<article class="card feature-card">
|
||||||
<div class="feature-icon">💬</div>
|
<div class="feature-icon">💬</div>
|
||||||
<p class="eyebrow">ON4KST Chat</p>
|
<p class="eyebrow">ON4KST Chat</p>
|
||||||
@@ -139,6 +99,22 @@
|
|||||||
<a href="/features/dx-cluster/">Learn more →</a>
|
<a href="/features/dx-cluster/">Learn more →</a>
|
||||||
</article>
|
</article>
|
||||||
|
|
||||||
|
<article class="card feature-card">
|
||||||
|
<div class="feature-icon"></div>
|
||||||
|
<p class="eyebrow"></p>
|
||||||
|
<h3><a href="/features/">KST4Contest Features</a></h3>
|
||||||
|
<p></p>
|
||||||
|
<a href="/features/">Learn more →</a>
|
||||||
|
</article>
|
||||||
|
|
||||||
|
<article class="card feature-card">
|
||||||
|
<div class="feature-icon">🔄</div>
|
||||||
|
<p class="eyebrow">Logger Integration</p>
|
||||||
|
<h3><a href="/features/log-sync/">Log Synchronization</a></h3>
|
||||||
|
<p>Connect ON4KST chat workflow with Win-Test, UCXLog and contest logging state.</p>
|
||||||
|
<a href="/features/log-sync/">Learn more →</a>
|
||||||
|
</article>
|
||||||
|
|
||||||
<article class="card feature-card">
|
<article class="card feature-card">
|
||||||
<div class="feature-icon">⚡</div>
|
<div class="feature-icon">⚡</div>
|
||||||
<p class="eyebrow">Operator Speed</p>
|
<p class="eyebrow">Operator Speed</p>
|
||||||
@@ -147,6 +123,30 @@
|
|||||||
<a href="/features/macros/">Learn more →</a>
|
<a href="/features/macros/">Learn more →</a>
|
||||||
</article>
|
</article>
|
||||||
|
|
||||||
|
<article class="card feature-card">
|
||||||
|
<div class="feature-icon">🎯</div>
|
||||||
|
<p class="eyebrow">Contest Workflow</p>
|
||||||
|
<h3><a href="/features/priority-score/">Priority Score System</a></h3>
|
||||||
|
<p>Find the most promising stations faster using contest-aware candidate scoring.</p>
|
||||||
|
<a href="/features/priority-score/">Learn more →</a>
|
||||||
|
</article>
|
||||||
|
|
||||||
|
<article class="card feature-card">
|
||||||
|
<div class="feature-icon">🔔</div>
|
||||||
|
<p class="eyebrow">Sked Management</p>
|
||||||
|
<h3><a href="/features/sked-reminder/">Sked Reminder</a></h3>
|
||||||
|
<p>Keep scheduled contacts visible and avoid missing time-critical skeds.</p>
|
||||||
|
<a href="/features/sked-reminder/">Learn more →</a>
|
||||||
|
</article>
|
||||||
|
|
||||||
|
<article class="card feature-card">
|
||||||
|
<div class="feature-icon">⏱️</div>
|
||||||
|
<p class="eyebrow">Contest Awareness</p>
|
||||||
|
<h3><a href="/features/timeline/">Timeline View</a></h3>
|
||||||
|
<p>See upcoming AP windows and candidate timing in a compact contest timeline.</p>
|
||||||
|
<a href="/features/timeline/">Learn more →</a>
|
||||||
|
</article>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
</main>
|
</main>
|
||||||
|
|||||||
@@ -17,7 +17,7 @@
|
|||||||
<meta name="twitter:title" content="Log Synchronization">
|
<meta name="twitter:title" content="Log Synchronization">
|
||||||
<meta name="twitter:description" content="Log synchronization helps KST4Contest understand worked stations, active bands and contest context.">
|
<meta name="twitter:description" content="Log synchronization helps KST4Contest understand worked stations, active bands and contest context.">
|
||||||
|
|
||||||
<link rel="stylesheet" href="/assets/css/main.css?v=1783381592602">
|
<link rel="stylesheet" href="/assets/css/main.css?v=1783425387839">
|
||||||
<link rel="alternate" type="application/rss+xml" title="KST4Contest News" href="/feed.xml">
|
<link rel="alternate" type="application/rss+xml" title="KST4Contest News" href="/feed.xml">
|
||||||
|
|
||||||
<meta property="og:image" content="https://kst4contest.hamradioonline.de/assets/social/kst4contest-og.png">
|
<meta property="og:image" content="https://kst4contest.hamradioonline.de/assets/social/kst4contest-og.png">
|
||||||
@@ -57,7 +57,7 @@
|
|||||||
|
|
||||||
<a href="/faq/">FAQ</a>
|
<a href="/faq/">FAQ</a>
|
||||||
|
|
||||||
<a class="nav-cta" href="https://github.com/praktimarc/kst4contest/releases/latest">Download</a>
|
<a class="nav-cta" href="/download/">Download</a>
|
||||||
</nav>
|
</nav>
|
||||||
</header>
|
</header>
|
||||||
|
|
||||||
@@ -101,6 +101,16 @@
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<a class="button secondary" href="/features/priority-score/">Priority Score System</a>
|
<a class="button secondary" href="/features/priority-score/">Priority Score System</a>
|
||||||
|
|
||||||
|
|
||||||
@@ -112,26 +122,6 @@
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<a class="button secondary" href="/features/dual-chat/">Dual Chat Categories</a>
|
<a class="button secondary" href="/features/dual-chat/">Dual Chat Categories</a>
|
||||||
|
|
||||||
@@ -141,6 +131,16 @@
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</article>
|
</article>
|
||||||
|
|||||||
@@ -17,7 +17,7 @@
|
|||||||
<meta name="twitter:title" content="Macros and Variables">
|
<meta name="twitter:title" content="Macros and Variables">
|
||||||
<meta name="twitter:description" content="Macros reduce repetitive typing and help operators respond quickly during active ON4KST contest sessions.">
|
<meta name="twitter:description" content="Macros reduce repetitive typing and help operators respond quickly during active ON4KST contest sessions.">
|
||||||
|
|
||||||
<link rel="stylesheet" href="/assets/css/main.css?v=1783381592602">
|
<link rel="stylesheet" href="/assets/css/main.css?v=1783425387839">
|
||||||
<link rel="alternate" type="application/rss+xml" title="KST4Contest News" href="/feed.xml">
|
<link rel="alternate" type="application/rss+xml" title="KST4Contest News" href="/feed.xml">
|
||||||
|
|
||||||
<meta property="og:image" content="https://kst4contest.hamradioonline.de/assets/social/kst4contest-og.png">
|
<meta property="og:image" content="https://kst4contest.hamradioonline.de/assets/social/kst4contest-og.png">
|
||||||
@@ -57,7 +57,7 @@
|
|||||||
|
|
||||||
<a href="/faq/">FAQ</a>
|
<a href="/faq/">FAQ</a>
|
||||||
|
|
||||||
<a class="nav-cta" href="https://github.com/praktimarc/kst4contest/releases/latest">Download</a>
|
<a class="nav-cta" href="/download/">Download</a>
|
||||||
</nav>
|
</nav>
|
||||||
</header>
|
</header>
|
||||||
|
|
||||||
@@ -106,27 +106,17 @@
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<a class="button secondary" href="/features/sked-reminder/">Sked Reminder</a>
|
<a class="button secondary" href="/features/sked-reminder/">Sked Reminder</a>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -140,6 +130,16 @@
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</article>
|
</article>
|
||||||
|
|||||||
@@ -17,7 +17,7 @@
|
|||||||
<meta name="twitter:title" content="Priority Score System">
|
<meta name="twitter:title" content="Priority Score System">
|
||||||
<meta name="twitter:description" content="KST4Contest ranks stations by activity, direction, sked context, band information, QRG hints and operator workflow signals.">
|
<meta name="twitter:description" content="KST4Contest ranks stations by activity, direction, sked context, band information, QRG hints and operator workflow signals.">
|
||||||
|
|
||||||
<link rel="stylesheet" href="/assets/css/main.css?v=1783381592602">
|
<link rel="stylesheet" href="/assets/css/main.css?v=1783425387839">
|
||||||
<link rel="alternate" type="application/rss+xml" title="KST4Contest News" href="/feed.xml">
|
<link rel="alternate" type="application/rss+xml" title="KST4Contest News" href="/feed.xml">
|
||||||
|
|
||||||
<meta property="og:image" content="https://kst4contest.hamradioonline.de/assets/social/kst4contest-og.png">
|
<meta property="og:image" content="https://kst4contest.hamradioonline.de/assets/social/kst4contest-og.png">
|
||||||
@@ -57,7 +57,7 @@
|
|||||||
|
|
||||||
<a href="/faq/">FAQ</a>
|
<a href="/faq/">FAQ</a>
|
||||||
|
|
||||||
<a class="nav-cta" href="https://github.com/praktimarc/kst4contest/releases/latest">Download</a>
|
<a class="nav-cta" href="/download/">Download</a>
|
||||||
</nav>
|
</nav>
|
||||||
</header>
|
</header>
|
||||||
|
|
||||||
@@ -111,26 +111,22 @@
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<a class="button secondary" href="/features/timeline/">Timeline View</a>
|
<a class="button secondary" href="/features/timeline/">Timeline View</a>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<a class="button secondary" href="/features/airscout/">AirScout Integration</a>
|
<a class="button secondary" href="/features/airscout/">AirScout Integration</a>
|
||||||
|
|
||||||
|
|
||||||
@@ -146,6 +142,16 @@
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -163,12 +169,6 @@
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</article>
|
</article>
|
||||||
|
|||||||
@@ -17,7 +17,7 @@
|
|||||||
<meta name="twitter:title" content="Sked Reminder">
|
<meta name="twitter:title" content="Sked Reminder">
|
||||||
<meta name="twitter:description" content="KST4Contest keeps skeds in focus while the operator handles chat traffic, logging, bands and aircraft scatter timing.">
|
<meta name="twitter:description" content="KST4Contest keeps skeds in focus while the operator handles chat traffic, logging, bands and aircraft scatter timing.">
|
||||||
|
|
||||||
<link rel="stylesheet" href="/assets/css/main.css?v=1783381592602">
|
<link rel="stylesheet" href="/assets/css/main.css?v=1783425387839">
|
||||||
<link rel="alternate" type="application/rss+xml" title="KST4Contest News" href="/feed.xml">
|
<link rel="alternate" type="application/rss+xml" title="KST4Contest News" href="/feed.xml">
|
||||||
|
|
||||||
<meta property="og:image" content="https://kst4contest.hamradioonline.de/assets/social/kst4contest-og.png">
|
<meta property="og:image" content="https://kst4contest.hamradioonline.de/assets/social/kst4contest-og.png">
|
||||||
@@ -57,7 +57,7 @@
|
|||||||
|
|
||||||
<a href="/faq/">FAQ</a>
|
<a href="/faq/">FAQ</a>
|
||||||
|
|
||||||
<a class="nav-cta" href="https://github.com/praktimarc/kst4contest/releases/latest">Download</a>
|
<a class="nav-cta" href="/download/">Download</a>
|
||||||
</nav>
|
</nav>
|
||||||
</header>
|
</header>
|
||||||
|
|
||||||
@@ -101,23 +101,19 @@
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<a class="button secondary" href="/features/priority-score/">Priority Score System</a>
|
<a class="button secondary" href="/features/priority-score/">Priority Score System</a>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -142,6 +138,20 @@
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -153,16 +163,6 @@
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</article>
|
</article>
|
||||||
|
|||||||
@@ -17,7 +17,7 @@
|
|||||||
<meta name="twitter:title" content="Timeline View">
|
<meta name="twitter:title" content="Timeline View">
|
||||||
<meta name="twitter:description" content="The timeline view helps operators understand short propagation windows and candidate timing during active contest operation.">
|
<meta name="twitter:description" content="The timeline view helps operators understand short propagation windows and candidate timing during active contest operation.">
|
||||||
|
|
||||||
<link rel="stylesheet" href="/assets/css/main.css?v=1783381592602">
|
<link rel="stylesheet" href="/assets/css/main.css?v=1783425387839">
|
||||||
<link rel="alternate" type="application/rss+xml" title="KST4Contest News" href="/feed.xml">
|
<link rel="alternate" type="application/rss+xml" title="KST4Contest News" href="/feed.xml">
|
||||||
|
|
||||||
<meta property="og:image" content="https://kst4contest.hamradioonline.de/assets/social/kst4contest-og.png">
|
<meta property="og:image" content="https://kst4contest.hamradioonline.de/assets/social/kst4contest-og.png">
|
||||||
@@ -57,7 +57,7 @@
|
|||||||
|
|
||||||
<a href="/faq/">FAQ</a>
|
<a href="/faq/">FAQ</a>
|
||||||
|
|
||||||
<a class="nav-cta" href="https://github.com/praktimarc/kst4contest/releases/latest">Download</a>
|
<a class="nav-cta" href="/download/">Download</a>
|
||||||
</nav>
|
</nav>
|
||||||
</header>
|
</header>
|
||||||
|
|
||||||
@@ -99,10 +99,6 @@
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<a class="button secondary" href="/features/airscout/">AirScout Integration</a>
|
<a class="button secondary" href="/features/airscout/">AirScout Integration</a>
|
||||||
|
|
||||||
|
|
||||||
@@ -116,6 +112,20 @@
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -131,16 +141,6 @@
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</article>
|
</article>
|
||||||
|
|||||||
+61
-61
@@ -17,7 +17,7 @@
|
|||||||
<meta name="twitter:title" content="KST4Contest – Contest-Optimized ON4KST Chat Client">
|
<meta name="twitter:title" content="KST4Contest – Contest-Optimized ON4KST Chat Client">
|
||||||
<meta name="twitter:description" content="KST4Contest is a modern ON4KST chat client built for VHF, UHF and SHF contest operation.">
|
<meta name="twitter:description" content="KST4Contest is a modern ON4KST chat client built for VHF, UHF and SHF contest operation.">
|
||||||
|
|
||||||
<link rel="stylesheet" href="/assets/css/main.css?v=1783381592602">
|
<link rel="stylesheet" href="/assets/css/main.css?v=1783425387839">
|
||||||
<link rel="alternate" type="application/rss+xml" title="KST4Contest News" href="/feed.xml">
|
<link rel="alternate" type="application/rss+xml" title="KST4Contest News" href="/feed.xml">
|
||||||
|
|
||||||
<meta property="og:image" content="https://kst4contest.hamradioonline.de/assets/social/kst4contest-og.png">
|
<meta property="og:image" content="https://kst4contest.hamradioonline.de/assets/social/kst4contest-og.png">
|
||||||
@@ -57,7 +57,7 @@
|
|||||||
|
|
||||||
<a href="/faq/">FAQ</a>
|
<a href="/faq/">FAQ</a>
|
||||||
|
|
||||||
<a class="nav-cta" href="https://github.com/praktimarc/kst4contest/releases/latest">Download</a>
|
<a class="nav-cta" href="/download/">Download</a>
|
||||||
</nav>
|
</nav>
|
||||||
</header>
|
</header>
|
||||||
|
|
||||||
@@ -74,7 +74,7 @@
|
|||||||
</p>
|
</p>
|
||||||
|
|
||||||
<div class="actions">
|
<div class="actions">
|
||||||
<a class="button" href="https://github.com/praktimarc/kst4contest/releases/latest">Download latest release</a>
|
<a class="button" href="/download/">Download KST4Contest</a>
|
||||||
<a class="button secondary" href="https://github.com/praktimarc/kst4contest">View on GitHub</a>
|
<a class="button secondary" href="https://github.com/praktimarc/kst4contest">View on GitHub</a>
|
||||||
<a class="button ghost" href="/manual/">Read manual</a>
|
<a class="button ghost" href="/manual/">Read manual</a>
|
||||||
</div>
|
</div>
|
||||||
@@ -89,20 +89,6 @@
|
|||||||
<div class="mock-grid">
|
<div class="mock-grid">
|
||||||
|
|
||||||
|
|
||||||
<div class="mini-card">
|
|
||||||
<strong> KST4Contest Features</strong>
|
|
||||||
<small></small>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<div class="mini-card">
|
|
||||||
<strong>🎯 Priority Score System</strong>
|
|
||||||
<small>Find the most promising stations faster using contest-aware candidate scoring.</small>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<div class="mini-card">
|
<div class="mini-card">
|
||||||
<strong>✈️ AirScout Integration</strong>
|
<strong>✈️ AirScout Integration</strong>
|
||||||
<small>Use aircraft scatter awareness directly inside your ON4KST contest workflow.</small>
|
<small>Use aircraft scatter awareness directly inside your ON4KST contest workflow.</small>
|
||||||
@@ -111,15 +97,22 @@
|
|||||||
|
|
||||||
|
|
||||||
<div class="mini-card">
|
<div class="mini-card">
|
||||||
<strong>⏱️ Timeline View</strong>
|
<strong>💬 Dual Chat Categories</strong>
|
||||||
<small>See upcoming AP windows and candidate timing in a compact contest timeline.</small>
|
<small>Operate in two ON4KST categories at once, for example VHF/UHF and microwave.</small>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<div class="mini-card">
|
<div class="mini-card">
|
||||||
<strong>🔔 Sked Reminder</strong>
|
<strong>📡 DXCluster Server</strong>
|
||||||
<small>Keep scheduled contacts visible and avoid missing time-critical skeds.</small>
|
<small>Use DXCluster information as part of the wider contest operating workflow.</small>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<div class="mini-card">
|
||||||
|
<strong> KST4Contest Features</strong>
|
||||||
|
<small></small>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
||||||
@@ -131,6 +124,13 @@
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<div class="mini-card">
|
||||||
|
<strong>⚡ Macros and Variables</strong>
|
||||||
|
<small>Send recurring contest messages faster with configurable macros and variables.</small>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -151,22 +151,6 @@
|
|||||||
|
|
||||||
<div class="grid">
|
<div class="grid">
|
||||||
|
|
||||||
<article class="card feature-card">
|
|
||||||
<div class="feature-icon"></div>
|
|
||||||
<p class="eyebrow"></p>
|
|
||||||
<h3><a href="/features/">KST4Contest Features</a></h3>
|
|
||||||
<p></p>
|
|
||||||
<a href="/features/">Learn more →</a>
|
|
||||||
</article>
|
|
||||||
|
|
||||||
<article class="card feature-card">
|
|
||||||
<div class="feature-icon">🎯</div>
|
|
||||||
<p class="eyebrow">Contest Workflow</p>
|
|
||||||
<h3><a href="/features/priority-score/">Priority Score System</a></h3>
|
|
||||||
<p>Find the most promising stations faster using contest-aware candidate scoring.</p>
|
|
||||||
<a href="/features/priority-score/">Learn more →</a>
|
|
||||||
</article>
|
|
||||||
|
|
||||||
<article class="card feature-card">
|
<article class="card feature-card">
|
||||||
<div class="feature-icon">✈️</div>
|
<div class="feature-icon">✈️</div>
|
||||||
<p class="eyebrow">Aircraft Scatter</p>
|
<p class="eyebrow">Aircraft Scatter</p>
|
||||||
@@ -175,30 +159,6 @@
|
|||||||
<a href="/features/airscout/">Learn more →</a>
|
<a href="/features/airscout/">Learn more →</a>
|
||||||
</article>
|
</article>
|
||||||
|
|
||||||
<article class="card feature-card">
|
|
||||||
<div class="feature-icon">⏱️</div>
|
|
||||||
<p class="eyebrow">Contest Awareness</p>
|
|
||||||
<h3><a href="/features/timeline/">Timeline View</a></h3>
|
|
||||||
<p>See upcoming AP windows and candidate timing in a compact contest timeline.</p>
|
|
||||||
<a href="/features/timeline/">Learn more →</a>
|
|
||||||
</article>
|
|
||||||
|
|
||||||
<article class="card feature-card">
|
|
||||||
<div class="feature-icon">🔔</div>
|
|
||||||
<p class="eyebrow">Sked Management</p>
|
|
||||||
<h3><a href="/features/sked-reminder/">Sked Reminder</a></h3>
|
|
||||||
<p>Keep scheduled contacts visible and avoid missing time-critical skeds.</p>
|
|
||||||
<a href="/features/sked-reminder/">Learn more →</a>
|
|
||||||
</article>
|
|
||||||
|
|
||||||
<article class="card feature-card">
|
|
||||||
<div class="feature-icon">🔄</div>
|
|
||||||
<p class="eyebrow">Logger Integration</p>
|
|
||||||
<h3><a href="/features/log-sync/">Log Synchronization</a></h3>
|
|
||||||
<p>Connect ON4KST chat workflow with Win-Test, UCXLog and contest logging state.</p>
|
|
||||||
<a href="/features/log-sync/">Learn more →</a>
|
|
||||||
</article>
|
|
||||||
|
|
||||||
<article class="card feature-card">
|
<article class="card feature-card">
|
||||||
<div class="feature-icon">💬</div>
|
<div class="feature-icon">💬</div>
|
||||||
<p class="eyebrow">ON4KST Chat</p>
|
<p class="eyebrow">ON4KST Chat</p>
|
||||||
@@ -215,6 +175,22 @@
|
|||||||
<a href="/features/dx-cluster/">Learn more →</a>
|
<a href="/features/dx-cluster/">Learn more →</a>
|
||||||
</article>
|
</article>
|
||||||
|
|
||||||
|
<article class="card feature-card">
|
||||||
|
<div class="feature-icon"></div>
|
||||||
|
<p class="eyebrow"></p>
|
||||||
|
<h3><a href="/features/">KST4Contest Features</a></h3>
|
||||||
|
<p></p>
|
||||||
|
<a href="/features/">Learn more →</a>
|
||||||
|
</article>
|
||||||
|
|
||||||
|
<article class="card feature-card">
|
||||||
|
<div class="feature-icon">🔄</div>
|
||||||
|
<p class="eyebrow">Logger Integration</p>
|
||||||
|
<h3><a href="/features/log-sync/">Log Synchronization</a></h3>
|
||||||
|
<p>Connect ON4KST chat workflow with Win-Test, UCXLog and contest logging state.</p>
|
||||||
|
<a href="/features/log-sync/">Learn more →</a>
|
||||||
|
</article>
|
||||||
|
|
||||||
<article class="card feature-card">
|
<article class="card feature-card">
|
||||||
<div class="feature-icon">⚡</div>
|
<div class="feature-icon">⚡</div>
|
||||||
<p class="eyebrow">Operator Speed</p>
|
<p class="eyebrow">Operator Speed</p>
|
||||||
@@ -223,6 +199,30 @@
|
|||||||
<a href="/features/macros/">Learn more →</a>
|
<a href="/features/macros/">Learn more →</a>
|
||||||
</article>
|
</article>
|
||||||
|
|
||||||
|
<article class="card feature-card">
|
||||||
|
<div class="feature-icon">🎯</div>
|
||||||
|
<p class="eyebrow">Contest Workflow</p>
|
||||||
|
<h3><a href="/features/priority-score/">Priority Score System</a></h3>
|
||||||
|
<p>Find the most promising stations faster using contest-aware candidate scoring.</p>
|
||||||
|
<a href="/features/priority-score/">Learn more →</a>
|
||||||
|
</article>
|
||||||
|
|
||||||
|
<article class="card feature-card">
|
||||||
|
<div class="feature-icon">🔔</div>
|
||||||
|
<p class="eyebrow">Sked Management</p>
|
||||||
|
<h3><a href="/features/sked-reminder/">Sked Reminder</a></h3>
|
||||||
|
<p>Keep scheduled contacts visible and avoid missing time-critical skeds.</p>
|
||||||
|
<a href="/features/sked-reminder/">Learn more →</a>
|
||||||
|
</article>
|
||||||
|
|
||||||
|
<article class="card feature-card">
|
||||||
|
<div class="feature-icon">⏱️</div>
|
||||||
|
<p class="eyebrow">Contest Awareness</p>
|
||||||
|
<h3><a href="/features/timeline/">Timeline View</a></h3>
|
||||||
|
<p>See upcoming AP windows and candidate timing in a compact contest timeline.</p>
|
||||||
|
<a href="/features/timeline/">Learn more →</a>
|
||||||
|
</article>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
|
|||||||
@@ -17,7 +17,7 @@
|
|||||||
<meta name="twitter:title" content="Legal Notice | KST4Contest">
|
<meta name="twitter:title" content="Legal Notice | KST4Contest">
|
||||||
<meta name="twitter:description" content="Legal notice for the KST4Contest website.">
|
<meta name="twitter:description" content="Legal notice for the KST4Contest website.">
|
||||||
|
|
||||||
<link rel="stylesheet" href="/assets/css/main.css?v=1783381592602">
|
<link rel="stylesheet" href="/assets/css/main.css?v=1783425387839">
|
||||||
<link rel="alternate" type="application/rss+xml" title="KST4Contest News" href="/feed.xml">
|
<link rel="alternate" type="application/rss+xml" title="KST4Contest News" href="/feed.xml">
|
||||||
|
|
||||||
<meta property="og:image" content="https://kst4contest.hamradioonline.de/assets/social/kst4contest-og.png">
|
<meta property="og:image" content="https://kst4contest.hamradioonline.de/assets/social/kst4contest-og.png">
|
||||||
@@ -57,7 +57,7 @@
|
|||||||
|
|
||||||
<a href="/faq/">FAQ</a>
|
<a href="/faq/">FAQ</a>
|
||||||
|
|
||||||
<a class="nav-cta" href="https://github.com/praktimarc/kst4contest/releases/latest">Download</a>
|
<a class="nav-cta" href="/download/">Download</a>
|
||||||
</nav>
|
</nav>
|
||||||
</header>
|
</header>
|
||||||
|
|
||||||
|
|||||||
@@ -17,7 +17,7 @@
|
|||||||
<meta name="twitter:title" content="{{ manual.title }} | KST4Contest Manual">
|
<meta name="twitter:title" content="{{ manual.title }} | KST4Contest Manual">
|
||||||
<meta name="twitter:description" content="KST4Contest manual page: {{ manual.title }}">
|
<meta name="twitter:description" content="KST4Contest manual page: {{ manual.title }}">
|
||||||
|
|
||||||
<link rel="stylesheet" href="/assets/css/main.css?v=1783381592602">
|
<link rel="stylesheet" href="/assets/css/main.css?v=1783425387839">
|
||||||
<link rel="alternate" type="application/rss+xml" title="KST4Contest News" href="/feed.xml">
|
<link rel="alternate" type="application/rss+xml" title="KST4Contest News" href="/feed.xml">
|
||||||
|
|
||||||
<meta property="og:image" content="https://kst4contest.hamradioonline.de/assets/social/kst4contest-og.png">
|
<meta property="og:image" content="https://kst4contest.hamradioonline.de/assets/social/kst4contest-og.png">
|
||||||
@@ -57,7 +57,7 @@
|
|||||||
|
|
||||||
<a href="/faq/">FAQ</a>
|
<a href="/faq/">FAQ</a>
|
||||||
|
|
||||||
<a class="nav-cta" href="https://github.com/praktimarc/kst4contest/releases/latest">Download</a>
|
<a class="nav-cta" href="/download/">Download</a>
|
||||||
</nav>
|
</nav>
|
||||||
</header>
|
</header>
|
||||||
|
|
||||||
|
|||||||
@@ -17,7 +17,7 @@
|
|||||||
<meta name="twitter:title" content="{{ manual.title }} | KST4Contest Manual">
|
<meta name="twitter:title" content="{{ manual.title }} | KST4Contest Manual">
|
||||||
<meta name="twitter:description" content="KST4Contest manual page: {{ manual.title }}">
|
<meta name="twitter:description" content="KST4Contest manual page: {{ manual.title }}">
|
||||||
|
|
||||||
<link rel="stylesheet" href="/assets/css/main.css?v=1783381592602">
|
<link rel="stylesheet" href="/assets/css/main.css?v=1783425387839">
|
||||||
<link rel="alternate" type="application/rss+xml" title="KST4Contest News" href="/feed.xml">
|
<link rel="alternate" type="application/rss+xml" title="KST4Contest News" href="/feed.xml">
|
||||||
|
|
||||||
<meta property="og:image" content="https://kst4contest.hamradioonline.de/assets/social/kst4contest-og.png">
|
<meta property="og:image" content="https://kst4contest.hamradioonline.de/assets/social/kst4contest-og.png">
|
||||||
@@ -57,7 +57,7 @@
|
|||||||
|
|
||||||
<a href="/faq/">FAQ</a>
|
<a href="/faq/">FAQ</a>
|
||||||
|
|
||||||
<a class="nav-cta" href="https://github.com/praktimarc/kst4contest/releases/latest">Download</a>
|
<a class="nav-cta" href="/download/">Download</a>
|
||||||
</nav>
|
</nav>
|
||||||
</header>
|
</header>
|
||||||
|
|
||||||
|
|||||||
@@ -17,7 +17,7 @@
|
|||||||
<meta name="twitter:title" content="{{ manual.title }} | KST4Contest Manual">
|
<meta name="twitter:title" content="{{ manual.title }} | KST4Contest Manual">
|
||||||
<meta name="twitter:description" content="KST4Contest manual page: {{ manual.title }}">
|
<meta name="twitter:description" content="KST4Contest manual page: {{ manual.title }}">
|
||||||
|
|
||||||
<link rel="stylesheet" href="/assets/css/main.css?v=1783381592602">
|
<link rel="stylesheet" href="/assets/css/main.css?v=1783425387839">
|
||||||
<link rel="alternate" type="application/rss+xml" title="KST4Contest News" href="/feed.xml">
|
<link rel="alternate" type="application/rss+xml" title="KST4Contest News" href="/feed.xml">
|
||||||
|
|
||||||
<meta property="og:image" content="https://kst4contest.hamradioonline.de/assets/social/kst4contest-og.png">
|
<meta property="og:image" content="https://kst4contest.hamradioonline.de/assets/social/kst4contest-og.png">
|
||||||
@@ -57,7 +57,7 @@
|
|||||||
|
|
||||||
<a href="/faq/">FAQ</a>
|
<a href="/faq/">FAQ</a>
|
||||||
|
|
||||||
<a class="nav-cta" href="https://github.com/praktimarc/kst4contest/releases/latest">Download</a>
|
<a class="nav-cta" href="/download/">Download</a>
|
||||||
</nav>
|
</nav>
|
||||||
</header>
|
</header>
|
||||||
|
|
||||||
|
|||||||
@@ -17,7 +17,7 @@
|
|||||||
<meta name="twitter:title" content="{{ manual.title }} | KST4Contest Manual">
|
<meta name="twitter:title" content="{{ manual.title }} | KST4Contest Manual">
|
||||||
<meta name="twitter:description" content="KST4Contest manual page: {{ manual.title }}">
|
<meta name="twitter:description" content="KST4Contest manual page: {{ manual.title }}">
|
||||||
|
|
||||||
<link rel="stylesheet" href="/assets/css/main.css?v=1783381592602">
|
<link rel="stylesheet" href="/assets/css/main.css?v=1783425387839">
|
||||||
<link rel="alternate" type="application/rss+xml" title="KST4Contest News" href="/feed.xml">
|
<link rel="alternate" type="application/rss+xml" title="KST4Contest News" href="/feed.xml">
|
||||||
|
|
||||||
<meta property="og:image" content="https://kst4contest.hamradioonline.de/assets/social/kst4contest-og.png">
|
<meta property="og:image" content="https://kst4contest.hamradioonline.de/assets/social/kst4contest-og.png">
|
||||||
@@ -57,7 +57,7 @@
|
|||||||
|
|
||||||
<a href="/faq/">FAQ</a>
|
<a href="/faq/">FAQ</a>
|
||||||
|
|
||||||
<a class="nav-cta" href="https://github.com/praktimarc/kst4contest/releases/latest">Download</a>
|
<a class="nav-cta" href="/download/">Download</a>
|
||||||
</nav>
|
</nav>
|
||||||
</header>
|
</header>
|
||||||
|
|
||||||
|
|||||||
@@ -17,7 +17,7 @@
|
|||||||
<meta name="twitter:title" content="{{ manual.title }} | KST4Contest Manual">
|
<meta name="twitter:title" content="{{ manual.title }} | KST4Contest Manual">
|
||||||
<meta name="twitter:description" content="KST4Contest manual page: {{ manual.title }}">
|
<meta name="twitter:description" content="KST4Contest manual page: {{ manual.title }}">
|
||||||
|
|
||||||
<link rel="stylesheet" href="/assets/css/main.css?v=1783381592602">
|
<link rel="stylesheet" href="/assets/css/main.css?v=1783425387839">
|
||||||
<link rel="alternate" type="application/rss+xml" title="KST4Contest News" href="/feed.xml">
|
<link rel="alternate" type="application/rss+xml" title="KST4Contest News" href="/feed.xml">
|
||||||
|
|
||||||
<meta property="og:image" content="https://kst4contest.hamradioonline.de/assets/social/kst4contest-og.png">
|
<meta property="og:image" content="https://kst4contest.hamradioonline.de/assets/social/kst4contest-og.png">
|
||||||
@@ -57,7 +57,7 @@
|
|||||||
|
|
||||||
<a href="/faq/">FAQ</a>
|
<a href="/faq/">FAQ</a>
|
||||||
|
|
||||||
<a class="nav-cta" href="https://github.com/praktimarc/kst4contest/releases/latest">Download</a>
|
<a class="nav-cta" href="/download/">Download</a>
|
||||||
</nav>
|
</nav>
|
||||||
</header>
|
</header>
|
||||||
|
|
||||||
|
|||||||
@@ -17,7 +17,7 @@
|
|||||||
<meta name="twitter:title" content="{{ manual.title }} | KST4Contest Manual">
|
<meta name="twitter:title" content="{{ manual.title }} | KST4Contest Manual">
|
||||||
<meta name="twitter:description" content="KST4Contest manual page: {{ manual.title }}">
|
<meta name="twitter:description" content="KST4Contest manual page: {{ manual.title }}">
|
||||||
|
|
||||||
<link rel="stylesheet" href="/assets/css/main.css?v=1783381592602">
|
<link rel="stylesheet" href="/assets/css/main.css?v=1783425387839">
|
||||||
<link rel="alternate" type="application/rss+xml" title="KST4Contest News" href="/feed.xml">
|
<link rel="alternate" type="application/rss+xml" title="KST4Contest News" href="/feed.xml">
|
||||||
|
|
||||||
<meta property="og:image" content="https://kst4contest.hamradioonline.de/assets/social/kst4contest-og.png">
|
<meta property="og:image" content="https://kst4contest.hamradioonline.de/assets/social/kst4contest-og.png">
|
||||||
@@ -57,7 +57,7 @@
|
|||||||
|
|
||||||
<a href="/faq/">FAQ</a>
|
<a href="/faq/">FAQ</a>
|
||||||
|
|
||||||
<a class="nav-cta" href="https://github.com/praktimarc/kst4contest/releases/latest">Download</a>
|
<a class="nav-cta" href="/download/">Download</a>
|
||||||
</nav>
|
</nav>
|
||||||
</header>
|
</header>
|
||||||
|
|
||||||
|
|||||||
@@ -17,7 +17,7 @@
|
|||||||
<meta name="twitter:title" content="KST4Contest Deutsches Handbuch">
|
<meta name="twitter:title" content="KST4Contest Deutsches Handbuch">
|
||||||
<meta name="twitter:description" content="Deutsches Benutzerhandbuch für KST4Contest.">
|
<meta name="twitter:description" content="Deutsches Benutzerhandbuch für KST4Contest.">
|
||||||
|
|
||||||
<link rel="stylesheet" href="/assets/css/main.css?v=1783381592602">
|
<link rel="stylesheet" href="/assets/css/main.css?v=1783425387839">
|
||||||
<link rel="alternate" type="application/rss+xml" title="KST4Contest News" href="/feed.xml">
|
<link rel="alternate" type="application/rss+xml" title="KST4Contest News" href="/feed.xml">
|
||||||
|
|
||||||
<meta property="og:image" content="https://kst4contest.hamradioonline.de/assets/social/kst4contest-og.png">
|
<meta property="og:image" content="https://kst4contest.hamradioonline.de/assets/social/kst4contest-og.png">
|
||||||
@@ -57,7 +57,7 @@
|
|||||||
|
|
||||||
<a href="/faq/">FAQ</a>
|
<a href="/faq/">FAQ</a>
|
||||||
|
|
||||||
<a class="nav-cta" href="https://github.com/praktimarc/kst4contest/releases/latest">Download</a>
|
<a class="nav-cta" href="/download/">Download</a>
|
||||||
</nav>
|
</nav>
|
||||||
</header>
|
</header>
|
||||||
|
|
||||||
|
|||||||
@@ -17,7 +17,7 @@
|
|||||||
<meta name="twitter:title" content="{{ manual.title }} | KST4Contest Manual">
|
<meta name="twitter:title" content="{{ manual.title }} | KST4Contest Manual">
|
||||||
<meta name="twitter:description" content="KST4Contest manual page: {{ manual.title }}">
|
<meta name="twitter:description" content="KST4Contest manual page: {{ manual.title }}">
|
||||||
|
|
||||||
<link rel="stylesheet" href="/assets/css/main.css?v=1783381592602">
|
<link rel="stylesheet" href="/assets/css/main.css?v=1783425387839">
|
||||||
<link rel="alternate" type="application/rss+xml" title="KST4Contest News" href="/feed.xml">
|
<link rel="alternate" type="application/rss+xml" title="KST4Contest News" href="/feed.xml">
|
||||||
|
|
||||||
<meta property="og:image" content="https://kst4contest.hamradioonline.de/assets/social/kst4contest-og.png">
|
<meta property="og:image" content="https://kst4contest.hamradioonline.de/assets/social/kst4contest-og.png">
|
||||||
@@ -57,7 +57,7 @@
|
|||||||
|
|
||||||
<a href="/faq/">FAQ</a>
|
<a href="/faq/">FAQ</a>
|
||||||
|
|
||||||
<a class="nav-cta" href="https://github.com/praktimarc/kst4contest/releases/latest">Download</a>
|
<a class="nav-cta" href="/download/">Download</a>
|
||||||
</nav>
|
</nav>
|
||||||
</header>
|
</header>
|
||||||
|
|
||||||
|
|||||||
@@ -17,7 +17,7 @@
|
|||||||
<meta name="twitter:title" content="{{ manual.title }} | KST4Contest Manual">
|
<meta name="twitter:title" content="{{ manual.title }} | KST4Contest Manual">
|
||||||
<meta name="twitter:description" content="KST4Contest manual page: {{ manual.title }}">
|
<meta name="twitter:description" content="KST4Contest manual page: {{ manual.title }}">
|
||||||
|
|
||||||
<link rel="stylesheet" href="/assets/css/main.css?v=1783381592602">
|
<link rel="stylesheet" href="/assets/css/main.css?v=1783425387839">
|
||||||
<link rel="alternate" type="application/rss+xml" title="KST4Contest News" href="/feed.xml">
|
<link rel="alternate" type="application/rss+xml" title="KST4Contest News" href="/feed.xml">
|
||||||
|
|
||||||
<meta property="og:image" content="https://kst4contest.hamradioonline.de/assets/social/kst4contest-og.png">
|
<meta property="og:image" content="https://kst4contest.hamradioonline.de/assets/social/kst4contest-og.png">
|
||||||
@@ -57,7 +57,7 @@
|
|||||||
|
|
||||||
<a href="/faq/">FAQ</a>
|
<a href="/faq/">FAQ</a>
|
||||||
|
|
||||||
<a class="nav-cta" href="https://github.com/praktimarc/kst4contest/releases/latest">Download</a>
|
<a class="nav-cta" href="/download/">Download</a>
|
||||||
</nav>
|
</nav>
|
||||||
</header>
|
</header>
|
||||||
|
|
||||||
|
|||||||
@@ -17,7 +17,7 @@
|
|||||||
<meta name="twitter:title" content="{{ manual.title }} | KST4Contest Manual">
|
<meta name="twitter:title" content="{{ manual.title }} | KST4Contest Manual">
|
||||||
<meta name="twitter:description" content="KST4Contest manual page: {{ manual.title }}">
|
<meta name="twitter:description" content="KST4Contest manual page: {{ manual.title }}">
|
||||||
|
|
||||||
<link rel="stylesheet" href="/assets/css/main.css?v=1783381592602">
|
<link rel="stylesheet" href="/assets/css/main.css?v=1783425387839">
|
||||||
<link rel="alternate" type="application/rss+xml" title="KST4Contest News" href="/feed.xml">
|
<link rel="alternate" type="application/rss+xml" title="KST4Contest News" href="/feed.xml">
|
||||||
|
|
||||||
<meta property="og:image" content="https://kst4contest.hamradioonline.de/assets/social/kst4contest-og.png">
|
<meta property="og:image" content="https://kst4contest.hamradioonline.de/assets/social/kst4contest-og.png">
|
||||||
@@ -57,7 +57,7 @@
|
|||||||
|
|
||||||
<a href="/faq/">FAQ</a>
|
<a href="/faq/">FAQ</a>
|
||||||
|
|
||||||
<a class="nav-cta" href="https://github.com/praktimarc/kst4contest/releases/latest">Download</a>
|
<a class="nav-cta" href="/download/">Download</a>
|
||||||
</nav>
|
</nav>
|
||||||
</header>
|
</header>
|
||||||
|
|
||||||
|
|||||||
@@ -17,7 +17,7 @@
|
|||||||
<meta name="twitter:title" content="{{ manual.title }} | KST4Contest Manual">
|
<meta name="twitter:title" content="{{ manual.title }} | KST4Contest Manual">
|
||||||
<meta name="twitter:description" content="KST4Contest manual page: {{ manual.title }}">
|
<meta name="twitter:description" content="KST4Contest manual page: {{ manual.title }}">
|
||||||
|
|
||||||
<link rel="stylesheet" href="/assets/css/main.css?v=1783381592602">
|
<link rel="stylesheet" href="/assets/css/main.css?v=1783425387839">
|
||||||
<link rel="alternate" type="application/rss+xml" title="KST4Contest News" href="/feed.xml">
|
<link rel="alternate" type="application/rss+xml" title="KST4Contest News" href="/feed.xml">
|
||||||
|
|
||||||
<meta property="og:image" content="https://kst4contest.hamradioonline.de/assets/social/kst4contest-og.png">
|
<meta property="og:image" content="https://kst4contest.hamradioonline.de/assets/social/kst4contest-og.png">
|
||||||
@@ -57,7 +57,7 @@
|
|||||||
|
|
||||||
<a href="/faq/">FAQ</a>
|
<a href="/faq/">FAQ</a>
|
||||||
|
|
||||||
<a class="nav-cta" href="https://github.com/praktimarc/kst4contest/releases/latest">Download</a>
|
<a class="nav-cta" href="/download/">Download</a>
|
||||||
</nav>
|
</nav>
|
||||||
</header>
|
</header>
|
||||||
|
|
||||||
|
|||||||
@@ -17,7 +17,7 @@
|
|||||||
<meta name="twitter:title" content="{{ manual.title }} | KST4Contest Manual">
|
<meta name="twitter:title" content="{{ manual.title }} | KST4Contest Manual">
|
||||||
<meta name="twitter:description" content="KST4Contest manual page: {{ manual.title }}">
|
<meta name="twitter:description" content="KST4Contest manual page: {{ manual.title }}">
|
||||||
|
|
||||||
<link rel="stylesheet" href="/assets/css/main.css?v=1783381592602">
|
<link rel="stylesheet" href="/assets/css/main.css?v=1783425387839">
|
||||||
<link rel="alternate" type="application/rss+xml" title="KST4Contest News" href="/feed.xml">
|
<link rel="alternate" type="application/rss+xml" title="KST4Contest News" href="/feed.xml">
|
||||||
|
|
||||||
<meta property="og:image" content="https://kst4contest.hamradioonline.de/assets/social/kst4contest-og.png">
|
<meta property="og:image" content="https://kst4contest.hamradioonline.de/assets/social/kst4contest-og.png">
|
||||||
@@ -57,7 +57,7 @@
|
|||||||
|
|
||||||
<a href="/faq/">FAQ</a>
|
<a href="/faq/">FAQ</a>
|
||||||
|
|
||||||
<a class="nav-cta" href="https://github.com/praktimarc/kst4contest/releases/latest">Download</a>
|
<a class="nav-cta" href="/download/">Download</a>
|
||||||
</nav>
|
</nav>
|
||||||
</header>
|
</header>
|
||||||
|
|
||||||
|
|||||||
@@ -17,7 +17,7 @@
|
|||||||
<meta name="twitter:title" content="{{ manual.title }} | KST4Contest Manual">
|
<meta name="twitter:title" content="{{ manual.title }} | KST4Contest Manual">
|
||||||
<meta name="twitter:description" content="KST4Contest manual page: {{ manual.title }}">
|
<meta name="twitter:description" content="KST4Contest manual page: {{ manual.title }}">
|
||||||
|
|
||||||
<link rel="stylesheet" href="/assets/css/main.css?v=1783381592602">
|
<link rel="stylesheet" href="/assets/css/main.css?v=1783425387839">
|
||||||
<link rel="alternate" type="application/rss+xml" title="KST4Contest News" href="/feed.xml">
|
<link rel="alternate" type="application/rss+xml" title="KST4Contest News" href="/feed.xml">
|
||||||
|
|
||||||
<meta property="og:image" content="https://kst4contest.hamradioonline.de/assets/social/kst4contest-og.png">
|
<meta property="og:image" content="https://kst4contest.hamradioonline.de/assets/social/kst4contest-og.png">
|
||||||
@@ -57,7 +57,7 @@
|
|||||||
|
|
||||||
<a href="/faq/">FAQ</a>
|
<a href="/faq/">FAQ</a>
|
||||||
|
|
||||||
<a class="nav-cta" href="https://github.com/praktimarc/kst4contest/releases/latest">Download</a>
|
<a class="nav-cta" href="/download/">Download</a>
|
||||||
</nav>
|
</nav>
|
||||||
</header>
|
</header>
|
||||||
|
|
||||||
|
|||||||
@@ -17,7 +17,7 @@
|
|||||||
<meta name="twitter:title" content="{{ manual.title }} | KST4Contest Manual">
|
<meta name="twitter:title" content="{{ manual.title }} | KST4Contest Manual">
|
||||||
<meta name="twitter:description" content="KST4Contest manual page: {{ manual.title }}">
|
<meta name="twitter:description" content="KST4Contest manual page: {{ manual.title }}">
|
||||||
|
|
||||||
<link rel="stylesheet" href="/assets/css/main.css?v=1783381592602">
|
<link rel="stylesheet" href="/assets/css/main.css?v=1783425387839">
|
||||||
<link rel="alternate" type="application/rss+xml" title="KST4Contest News" href="/feed.xml">
|
<link rel="alternate" type="application/rss+xml" title="KST4Contest News" href="/feed.xml">
|
||||||
|
|
||||||
<meta property="og:image" content="https://kst4contest.hamradioonline.de/assets/social/kst4contest-og.png">
|
<meta property="og:image" content="https://kst4contest.hamradioonline.de/assets/social/kst4contest-og.png">
|
||||||
@@ -57,7 +57,7 @@
|
|||||||
|
|
||||||
<a href="/faq/">FAQ</a>
|
<a href="/faq/">FAQ</a>
|
||||||
|
|
||||||
<a class="nav-cta" href="https://github.com/praktimarc/kst4contest/releases/latest">Download</a>
|
<a class="nav-cta" href="/download/">Download</a>
|
||||||
</nav>
|
</nav>
|
||||||
</header>
|
</header>
|
||||||
|
|
||||||
|
|||||||
@@ -17,7 +17,7 @@
|
|||||||
<meta name="twitter:title" content="{{ manual.title }} | KST4Contest Manual">
|
<meta name="twitter:title" content="{{ manual.title }} | KST4Contest Manual">
|
||||||
<meta name="twitter:description" content="KST4Contest manual page: {{ manual.title }}">
|
<meta name="twitter:description" content="KST4Contest manual page: {{ manual.title }}">
|
||||||
|
|
||||||
<link rel="stylesheet" href="/assets/css/main.css?v=1783381592602">
|
<link rel="stylesheet" href="/assets/css/main.css?v=1783425387839">
|
||||||
<link rel="alternate" type="application/rss+xml" title="KST4Contest News" href="/feed.xml">
|
<link rel="alternate" type="application/rss+xml" title="KST4Contest News" href="/feed.xml">
|
||||||
|
|
||||||
<meta property="og:image" content="https://kst4contest.hamradioonline.de/assets/social/kst4contest-og.png">
|
<meta property="og:image" content="https://kst4contest.hamradioonline.de/assets/social/kst4contest-og.png">
|
||||||
@@ -57,7 +57,7 @@
|
|||||||
|
|
||||||
<a href="/faq/">FAQ</a>
|
<a href="/faq/">FAQ</a>
|
||||||
|
|
||||||
<a class="nav-cta" href="https://github.com/praktimarc/kst4contest/releases/latest">Download</a>
|
<a class="nav-cta" href="/download/">Download</a>
|
||||||
</nav>
|
</nav>
|
||||||
</header>
|
</header>
|
||||||
|
|
||||||
|
|||||||
@@ -17,7 +17,7 @@
|
|||||||
<meta name="twitter:title" content="{{ manual.title }} | KST4Contest Manual">
|
<meta name="twitter:title" content="{{ manual.title }} | KST4Contest Manual">
|
||||||
<meta name="twitter:description" content="KST4Contest manual page: {{ manual.title }}">
|
<meta name="twitter:description" content="KST4Contest manual page: {{ manual.title }}">
|
||||||
|
|
||||||
<link rel="stylesheet" href="/assets/css/main.css?v=1783381592602">
|
<link rel="stylesheet" href="/assets/css/main.css?v=1783425387839">
|
||||||
<link rel="alternate" type="application/rss+xml" title="KST4Contest News" href="/feed.xml">
|
<link rel="alternate" type="application/rss+xml" title="KST4Contest News" href="/feed.xml">
|
||||||
|
|
||||||
<meta property="og:image" content="https://kst4contest.hamradioonline.de/assets/social/kst4contest-og.png">
|
<meta property="og:image" content="https://kst4contest.hamradioonline.de/assets/social/kst4contest-og.png">
|
||||||
@@ -57,7 +57,7 @@
|
|||||||
|
|
||||||
<a href="/faq/">FAQ</a>
|
<a href="/faq/">FAQ</a>
|
||||||
|
|
||||||
<a class="nav-cta" href="https://github.com/praktimarc/kst4contest/releases/latest">Download</a>
|
<a class="nav-cta" href="/download/">Download</a>
|
||||||
</nav>
|
</nav>
|
||||||
</header>
|
</header>
|
||||||
|
|
||||||
|
|||||||
@@ -17,7 +17,7 @@
|
|||||||
<meta name="twitter:title" content="{{ manual.title }} | KST4Contest Manual">
|
<meta name="twitter:title" content="{{ manual.title }} | KST4Contest Manual">
|
||||||
<meta name="twitter:description" content="KST4Contest manual page: {{ manual.title }}">
|
<meta name="twitter:description" content="KST4Contest manual page: {{ manual.title }}">
|
||||||
|
|
||||||
<link rel="stylesheet" href="/assets/css/main.css?v=1783381592602">
|
<link rel="stylesheet" href="/assets/css/main.css?v=1783425387839">
|
||||||
<link rel="alternate" type="application/rss+xml" title="KST4Contest News" href="/feed.xml">
|
<link rel="alternate" type="application/rss+xml" title="KST4Contest News" href="/feed.xml">
|
||||||
|
|
||||||
<meta property="og:image" content="https://kst4contest.hamradioonline.de/assets/social/kst4contest-og.png">
|
<meta property="og:image" content="https://kst4contest.hamradioonline.de/assets/social/kst4contest-og.png">
|
||||||
@@ -57,7 +57,7 @@
|
|||||||
|
|
||||||
<a href="/faq/">FAQ</a>
|
<a href="/faq/">FAQ</a>
|
||||||
|
|
||||||
<a class="nav-cta" href="https://github.com/praktimarc/kst4contest/releases/latest">Download</a>
|
<a class="nav-cta" href="/download/">Download</a>
|
||||||
</nav>
|
</nav>
|
||||||
</header>
|
</header>
|
||||||
|
|
||||||
|
|||||||
@@ -17,7 +17,7 @@
|
|||||||
<meta name="twitter:title" content="KST4Contest English Manual">
|
<meta name="twitter:title" content="KST4Contest English Manual">
|
||||||
<meta name="twitter:description" content="English user manual for KST4Contest.">
|
<meta name="twitter:description" content="English user manual for KST4Contest.">
|
||||||
|
|
||||||
<link rel="stylesheet" href="/assets/css/main.css?v=1783381592602">
|
<link rel="stylesheet" href="/assets/css/main.css?v=1783425387839">
|
||||||
<link rel="alternate" type="application/rss+xml" title="KST4Contest News" href="/feed.xml">
|
<link rel="alternate" type="application/rss+xml" title="KST4Contest News" href="/feed.xml">
|
||||||
|
|
||||||
<meta property="og:image" content="https://kst4contest.hamradioonline.de/assets/social/kst4contest-og.png">
|
<meta property="og:image" content="https://kst4contest.hamradioonline.de/assets/social/kst4contest-og.png">
|
||||||
@@ -57,7 +57,7 @@
|
|||||||
|
|
||||||
<a href="/faq/">FAQ</a>
|
<a href="/faq/">FAQ</a>
|
||||||
|
|
||||||
<a class="nav-cta" href="https://github.com/praktimarc/kst4contest/releases/latest">Download</a>
|
<a class="nav-cta" href="/download/">Download</a>
|
||||||
</nav>
|
</nav>
|
||||||
</header>
|
</header>
|
||||||
|
|
||||||
|
|||||||
@@ -17,7 +17,7 @@
|
|||||||
<meta name="twitter:title" content="{{ manual.title }} | KST4Contest Manual">
|
<meta name="twitter:title" content="{{ manual.title }} | KST4Contest Manual">
|
||||||
<meta name="twitter:description" content="KST4Contest manual page: {{ manual.title }}">
|
<meta name="twitter:description" content="KST4Contest manual page: {{ manual.title }}">
|
||||||
|
|
||||||
<link rel="stylesheet" href="/assets/css/main.css?v=1783381592602">
|
<link rel="stylesheet" href="/assets/css/main.css?v=1783425387839">
|
||||||
<link rel="alternate" type="application/rss+xml" title="KST4Contest News" href="/feed.xml">
|
<link rel="alternate" type="application/rss+xml" title="KST4Contest News" href="/feed.xml">
|
||||||
|
|
||||||
<meta property="og:image" content="https://kst4contest.hamradioonline.de/assets/social/kst4contest-og.png">
|
<meta property="og:image" content="https://kst4contest.hamradioonline.de/assets/social/kst4contest-og.png">
|
||||||
@@ -57,7 +57,7 @@
|
|||||||
|
|
||||||
<a href="/faq/">FAQ</a>
|
<a href="/faq/">FAQ</a>
|
||||||
|
|
||||||
<a class="nav-cta" href="https://github.com/praktimarc/kst4contest/releases/latest">Download</a>
|
<a class="nav-cta" href="/download/">Download</a>
|
||||||
</nav>
|
</nav>
|
||||||
</header>
|
</header>
|
||||||
|
|
||||||
|
|||||||
@@ -17,7 +17,7 @@
|
|||||||
<meta name="twitter:title" content="{{ manual.title }} | KST4Contest Manual">
|
<meta name="twitter:title" content="{{ manual.title }} | KST4Contest Manual">
|
||||||
<meta name="twitter:description" content="KST4Contest manual page: {{ manual.title }}">
|
<meta name="twitter:description" content="KST4Contest manual page: {{ manual.title }}">
|
||||||
|
|
||||||
<link rel="stylesheet" href="/assets/css/main.css?v=1783381592602">
|
<link rel="stylesheet" href="/assets/css/main.css?v=1783425387839">
|
||||||
<link rel="alternate" type="application/rss+xml" title="KST4Contest News" href="/feed.xml">
|
<link rel="alternate" type="application/rss+xml" title="KST4Contest News" href="/feed.xml">
|
||||||
|
|
||||||
<meta property="og:image" content="https://kst4contest.hamradioonline.de/assets/social/kst4contest-og.png">
|
<meta property="og:image" content="https://kst4contest.hamradioonline.de/assets/social/kst4contest-og.png">
|
||||||
@@ -57,7 +57,7 @@
|
|||||||
|
|
||||||
<a href="/faq/">FAQ</a>
|
<a href="/faq/">FAQ</a>
|
||||||
|
|
||||||
<a class="nav-cta" href="https://github.com/praktimarc/kst4contest/releases/latest">Download</a>
|
<a class="nav-cta" href="/download/">Download</a>
|
||||||
</nav>
|
</nav>
|
||||||
</header>
|
</header>
|
||||||
|
|
||||||
|
|||||||
@@ -17,7 +17,7 @@
|
|||||||
<meta name="twitter:title" content="{{ manual.title }} | KST4Contest Manual">
|
<meta name="twitter:title" content="{{ manual.title }} | KST4Contest Manual">
|
||||||
<meta name="twitter:description" content="KST4Contest manual page: {{ manual.title }}">
|
<meta name="twitter:description" content="KST4Contest manual page: {{ manual.title }}">
|
||||||
|
|
||||||
<link rel="stylesheet" href="/assets/css/main.css?v=1783381592602">
|
<link rel="stylesheet" href="/assets/css/main.css?v=1783425387839">
|
||||||
<link rel="alternate" type="application/rss+xml" title="KST4Contest News" href="/feed.xml">
|
<link rel="alternate" type="application/rss+xml" title="KST4Contest News" href="/feed.xml">
|
||||||
|
|
||||||
<meta property="og:image" content="https://kst4contest.hamradioonline.de/assets/social/kst4contest-og.png">
|
<meta property="og:image" content="https://kst4contest.hamradioonline.de/assets/social/kst4contest-og.png">
|
||||||
@@ -57,7 +57,7 @@
|
|||||||
|
|
||||||
<a href="/faq/">FAQ</a>
|
<a href="/faq/">FAQ</a>
|
||||||
|
|
||||||
<a class="nav-cta" href="https://github.com/praktimarc/kst4contest/releases/latest">Download</a>
|
<a class="nav-cta" href="/download/">Download</a>
|
||||||
</nav>
|
</nav>
|
||||||
</header>
|
</header>
|
||||||
|
|
||||||
|
|||||||
@@ -17,7 +17,7 @@
|
|||||||
<meta name="twitter:title" content="{{ manual.title }} | KST4Contest Manual">
|
<meta name="twitter:title" content="{{ manual.title }} | KST4Contest Manual">
|
||||||
<meta name="twitter:description" content="KST4Contest manual page: {{ manual.title }}">
|
<meta name="twitter:description" content="KST4Contest manual page: {{ manual.title }}">
|
||||||
|
|
||||||
<link rel="stylesheet" href="/assets/css/main.css?v=1783381592602">
|
<link rel="stylesheet" href="/assets/css/main.css?v=1783425387839">
|
||||||
<link rel="alternate" type="application/rss+xml" title="KST4Contest News" href="/feed.xml">
|
<link rel="alternate" type="application/rss+xml" title="KST4Contest News" href="/feed.xml">
|
||||||
|
|
||||||
<meta property="og:image" content="https://kst4contest.hamradioonline.de/assets/social/kst4contest-og.png">
|
<meta property="og:image" content="https://kst4contest.hamradioonline.de/assets/social/kst4contest-og.png">
|
||||||
@@ -57,7 +57,7 @@
|
|||||||
|
|
||||||
<a href="/faq/">FAQ</a>
|
<a href="/faq/">FAQ</a>
|
||||||
|
|
||||||
<a class="nav-cta" href="https://github.com/praktimarc/kst4contest/releases/latest">Download</a>
|
<a class="nav-cta" href="/download/">Download</a>
|
||||||
</nav>
|
</nav>
|
||||||
</header>
|
</header>
|
||||||
|
|
||||||
|
|||||||
@@ -17,7 +17,7 @@
|
|||||||
<meta name="twitter:title" content="KST4Contest Manual">
|
<meta name="twitter:title" content="KST4Contest Manual">
|
||||||
<meta name="twitter:description" content="Online manual for KST4Contest, the contest-optimized ON4KST chat client.">
|
<meta name="twitter:description" content="Online manual for KST4Contest, the contest-optimized ON4KST chat client.">
|
||||||
|
|
||||||
<link rel="stylesheet" href="/assets/css/main.css?v=1783381592602">
|
<link rel="stylesheet" href="/assets/css/main.css?v=1783425387839">
|
||||||
<link rel="alternate" type="application/rss+xml" title="KST4Contest News" href="/feed.xml">
|
<link rel="alternate" type="application/rss+xml" title="KST4Contest News" href="/feed.xml">
|
||||||
|
|
||||||
<meta property="og:image" content="https://kst4contest.hamradioonline.de/assets/social/kst4contest-og.png">
|
<meta property="og:image" content="https://kst4contest.hamradioonline.de/assets/social/kst4contest-og.png">
|
||||||
@@ -57,7 +57,7 @@
|
|||||||
|
|
||||||
<a href="/faq/">FAQ</a>
|
<a href="/faq/">FAQ</a>
|
||||||
|
|
||||||
<a class="nav-cta" href="https://github.com/praktimarc/kst4contest/releases/latest">Download</a>
|
<a class="nav-cta" href="/download/">Download</a>
|
||||||
</nav>
|
</nav>
|
||||||
</header>
|
</header>
|
||||||
|
|
||||||
|
|||||||
@@ -17,7 +17,7 @@
|
|||||||
<meta name="twitter:title" content="KST4Contest Website Launch">
|
<meta name="twitter:title" content="KST4Contest Website Launch">
|
||||||
<meta name="twitter:description" content="Contest-optimized ON4KST chat client for VHF, UHF and SHF ham radio contests.">
|
<meta name="twitter:description" content="Contest-optimized ON4KST chat client for VHF, UHF and SHF ham radio contests.">
|
||||||
|
|
||||||
<link rel="stylesheet" href="/assets/css/main.css?v=1783381592602">
|
<link rel="stylesheet" href="/assets/css/main.css?v=1783425387839">
|
||||||
<link rel="alternate" type="application/rss+xml" title="KST4Contest News" href="/feed.xml">
|
<link rel="alternate" type="application/rss+xml" title="KST4Contest News" href="/feed.xml">
|
||||||
|
|
||||||
<meta property="og:image" content="https://kst4contest.hamradioonline.de/assets/social/kst4contest-og.png">
|
<meta property="og:image" content="https://kst4contest.hamradioonline.de/assets/social/kst4contest-og.png">
|
||||||
@@ -57,7 +57,7 @@
|
|||||||
|
|
||||||
<a href="/faq/">FAQ</a>
|
<a href="/faq/">FAQ</a>
|
||||||
|
|
||||||
<a class="nav-cta" href="https://github.com/praktimarc/kst4contest/releases/latest">Download</a>
|
<a class="nav-cta" href="/download/">Download</a>
|
||||||
</nav>
|
</nav>
|
||||||
</header>
|
</header>
|
||||||
|
|
||||||
|
|||||||
@@ -17,7 +17,7 @@
|
|||||||
<meta name="twitter:title" content="KST4Contest News">
|
<meta name="twitter:title" content="KST4Contest News">
|
||||||
<meta name="twitter:description" content="News, release updates and development notes for KST4Contest.">
|
<meta name="twitter:description" content="News, release updates and development notes for KST4Contest.">
|
||||||
|
|
||||||
<link rel="stylesheet" href="/assets/css/main.css?v=1783381592602">
|
<link rel="stylesheet" href="/assets/css/main.css?v=1783425387839">
|
||||||
<link rel="alternate" type="application/rss+xml" title="KST4Contest News" href="/feed.xml">
|
<link rel="alternate" type="application/rss+xml" title="KST4Contest News" href="/feed.xml">
|
||||||
|
|
||||||
<meta property="og:image" content="https://kst4contest.hamradioonline.de/assets/social/kst4contest-og.png">
|
<meta property="og:image" content="https://kst4contest.hamradioonline.de/assets/social/kst4contest-og.png">
|
||||||
@@ -57,7 +57,7 @@
|
|||||||
|
|
||||||
<a href="/faq/">FAQ</a>
|
<a href="/faq/">FAQ</a>
|
||||||
|
|
||||||
<a class="nav-cta" href="https://github.com/praktimarc/kst4contest/releases/latest">Download</a>
|
<a class="nav-cta" href="/download/">Download</a>
|
||||||
</nav>
|
</nav>
|
||||||
</header>
|
</header>
|
||||||
|
|
||||||
|
|||||||
@@ -17,7 +17,7 @@
|
|||||||
<meta name="twitter:title" content="Privacy Policy | KST4Contest">
|
<meta name="twitter:title" content="Privacy Policy | KST4Contest">
|
||||||
<meta name="twitter:description" content="Privacy policy for the KST4Contest website.">
|
<meta name="twitter:description" content="Privacy policy for the KST4Contest website.">
|
||||||
|
|
||||||
<link rel="stylesheet" href="/assets/css/main.css?v=1783381592602">
|
<link rel="stylesheet" href="/assets/css/main.css?v=1783425387839">
|
||||||
<link rel="alternate" type="application/rss+xml" title="KST4Contest News" href="/feed.xml">
|
<link rel="alternate" type="application/rss+xml" title="KST4Contest News" href="/feed.xml">
|
||||||
|
|
||||||
<meta property="og:image" content="https://kst4contest.hamradioonline.de/assets/social/kst4contest-og.png">
|
<meta property="og:image" content="https://kst4contest.hamradioonline.de/assets/social/kst4contest-og.png">
|
||||||
@@ -57,7 +57,7 @@
|
|||||||
|
|
||||||
<a href="/faq/">FAQ</a>
|
<a href="/faq/">FAQ</a>
|
||||||
|
|
||||||
<a class="nav-cta" href="https://github.com/praktimarc/kst4contest/releases/latest">Download</a>
|
<a class="nav-cta" href="/download/">Download</a>
|
||||||
</nav>
|
</nav>
|
||||||
</header>
|
</header>
|
||||||
|
|
||||||
|
|||||||
@@ -17,7 +17,7 @@
|
|||||||
<meta name="twitter:title" content="KST4Contest Screenshots">
|
<meta name="twitter:title" content="KST4Contest Screenshots">
|
||||||
<meta name="twitter:description" content="Screenshots of KST4Contest, the contest-optimized ON4KST chat client for VHF, UHF and SHF operators.">
|
<meta name="twitter:description" content="Screenshots of KST4Contest, the contest-optimized ON4KST chat client for VHF, UHF and SHF operators.">
|
||||||
|
|
||||||
<link rel="stylesheet" href="/assets/css/main.css?v=1783381592602">
|
<link rel="stylesheet" href="/assets/css/main.css?v=1783425387839">
|
||||||
<link rel="alternate" type="application/rss+xml" title="KST4Contest News" href="/feed.xml">
|
<link rel="alternate" type="application/rss+xml" title="KST4Contest News" href="/feed.xml">
|
||||||
|
|
||||||
<meta property="og:image" content="https://kst4contest.hamradioonline.de/assets/social/kst4contest-og.png">
|
<meta property="og:image" content="https://kst4contest.hamradioonline.de/assets/social/kst4contest-og.png">
|
||||||
@@ -57,7 +57,7 @@
|
|||||||
|
|
||||||
<a href="/faq/">FAQ</a>
|
<a href="/faq/">FAQ</a>
|
||||||
|
|
||||||
<a class="nav-cta" href="https://github.com/praktimarc/kst4contest/releases/latest">Download</a>
|
<a class="nav-cta" href="/download/">Download</a>
|
||||||
</nav>
|
</nav>
|
||||||
</header>
|
</header>
|
||||||
|
|
||||||
|
|||||||
+45
-45
@@ -1,61 +1,29 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
|
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
|
||||||
<url>
|
|
||||||
<loc>https://kst4contest.hamradioonline.de/</loc>
|
|
||||||
<lastmod>2026-07-05</lastmod>
|
|
||||||
</url>
|
|
||||||
<url>
|
|
||||||
<loc>https://kst4contest.hamradioonline.de/manual/</loc>
|
|
||||||
<lastmod>2026-07-05</lastmod>
|
|
||||||
</url>
|
|
||||||
<url>
|
|
||||||
<loc>https://kst4contest.hamradioonline.de/manual/en/</loc>
|
|
||||||
<lastmod>2026-07-05</lastmod>
|
|
||||||
</url>
|
|
||||||
<url>
|
|
||||||
<loc>https://kst4contest.hamradioonline.de/download/</loc>
|
|
||||||
<lastmod>2026-07-05</lastmod>
|
|
||||||
</url>
|
|
||||||
<url>
|
|
||||||
<loc>https://kst4contest.hamradioonline.de/features/</loc>
|
|
||||||
<lastmod>2026-07-06</lastmod>
|
|
||||||
</url>
|
|
||||||
<url>
|
|
||||||
<loc>https://kst4contest.hamradioonline.de/screenshots/</loc>
|
|
||||||
<lastmod>2026-07-06</lastmod>
|
|
||||||
</url>
|
|
||||||
<url>
|
<url>
|
||||||
<loc>https://kst4contest.hamradioonline.de/faq/</loc>
|
<loc>https://kst4contest.hamradioonline.de/faq/</loc>
|
||||||
<lastmod>2026-07-06</lastmod>
|
<lastmod>2026-07-06</lastmod>
|
||||||
</url>
|
</url>
|
||||||
<url>
|
|
||||||
<loc>https://kst4contest.hamradioonline.de/manual/de/</loc>
|
|
||||||
<lastmod>2026-07-06</lastmod>
|
|
||||||
</url>
|
|
||||||
<url>
|
<url>
|
||||||
<loc>https://kst4contest.hamradioonline.de/manual/de/airscout-integration/</loc>
|
<loc>https://kst4contest.hamradioonline.de/manual/de/airscout-integration/</loc>
|
||||||
<lastmod>2026-07-06</lastmod>
|
<lastmod>2026-07-06</lastmod>
|
||||||
</url>
|
</url>
|
||||||
<url>
|
<url>
|
||||||
<loc>https://kst4contest.hamradioonline.de/features/priority-score/</loc>
|
<loc>https://kst4contest.hamradioonline.de/manual/de/</loc>
|
||||||
|
<lastmod>2026-07-06</lastmod>
|
||||||
|
</url>
|
||||||
|
<url>
|
||||||
|
<loc>https://kst4contest.hamradioonline.de/manual/en/</loc>
|
||||||
|
<lastmod>2026-07-06</lastmod>
|
||||||
|
</url>
|
||||||
|
<url>
|
||||||
|
<loc>https://kst4contest.hamradioonline.de/manual/</loc>
|
||||||
<lastmod>2026-07-06</lastmod>
|
<lastmod>2026-07-06</lastmod>
|
||||||
</url>
|
</url>
|
||||||
<url>
|
<url>
|
||||||
<loc>https://kst4contest.hamradioonline.de/features/airscout/</loc>
|
<loc>https://kst4contest.hamradioonline.de/features/airscout/</loc>
|
||||||
<lastmod>2026-07-06</lastmod>
|
<lastmod>2026-07-06</lastmod>
|
||||||
</url>
|
</url>
|
||||||
<url>
|
|
||||||
<loc>https://kst4contest.hamradioonline.de/features/timeline/</loc>
|
|
||||||
<lastmod>2026-07-06</lastmod>
|
|
||||||
</url>
|
|
||||||
<url>
|
|
||||||
<loc>https://kst4contest.hamradioonline.de/features/sked-reminder/</loc>
|
|
||||||
<lastmod>2026-07-06</lastmod>
|
|
||||||
</url>
|
|
||||||
<url>
|
|
||||||
<loc>https://kst4contest.hamradioonline.de/features/log-sync/</loc>
|
|
||||||
<lastmod>2026-07-06</lastmod>
|
|
||||||
</url>
|
|
||||||
<url>
|
<url>
|
||||||
<loc>https://kst4contest.hamradioonline.de/features/dual-chat/</loc>
|
<loc>https://kst4contest.hamradioonline.de/features/dual-chat/</loc>
|
||||||
<lastmod>2026-07-06</lastmod>
|
<lastmod>2026-07-06</lastmod>
|
||||||
@@ -64,28 +32,60 @@
|
|||||||
<loc>https://kst4contest.hamradioonline.de/features/dx-cluster/</loc>
|
<loc>https://kst4contest.hamradioonline.de/features/dx-cluster/</loc>
|
||||||
<lastmod>2026-07-06</lastmod>
|
<lastmod>2026-07-06</lastmod>
|
||||||
</url>
|
</url>
|
||||||
|
<url>
|
||||||
|
<loc>https://kst4contest.hamradioonline.de/features/</loc>
|
||||||
|
<lastmod>2026-07-06</lastmod>
|
||||||
|
</url>
|
||||||
|
<url>
|
||||||
|
<loc>https://kst4contest.hamradioonline.de/features/log-sync/</loc>
|
||||||
|
<lastmod>2026-07-06</lastmod>
|
||||||
|
</url>
|
||||||
<url>
|
<url>
|
||||||
<loc>https://kst4contest.hamradioonline.de/features/macros/</loc>
|
<loc>https://kst4contest.hamradioonline.de/features/macros/</loc>
|
||||||
<lastmod>2026-07-06</lastmod>
|
<lastmod>2026-07-06</lastmod>
|
||||||
</url>
|
</url>
|
||||||
<url>
|
<url>
|
||||||
<loc>https://kst4contest.hamradioonline.de/legal-notice/</loc>
|
<loc>https://kst4contest.hamradioonline.de/features/priority-score/</loc>
|
||||||
<lastmod>2026-07-06</lastmod>
|
<lastmod>2026-07-06</lastmod>
|
||||||
</url>
|
</url>
|
||||||
<url>
|
<url>
|
||||||
<loc>https://kst4contest.hamradioonline.de/privacy/</loc>
|
<loc>https://kst4contest.hamradioonline.de/features/sked-reminder/</loc>
|
||||||
<lastmod>2026-07-06</lastmod>
|
<lastmod>2026-07-06</lastmod>
|
||||||
</url>
|
</url>
|
||||||
<url>
|
<url>
|
||||||
<loc>https://kst4contest.hamradioonline.de/contact/</loc>
|
<loc>https://kst4contest.hamradioonline.de/features/timeline/</loc>
|
||||||
<lastmod>2026-07-06</lastmod>
|
<lastmod>2026-07-06</lastmod>
|
||||||
</url>
|
</url>
|
||||||
<url>
|
<url>
|
||||||
<loc>https://kst4contest.hamradioonline.de/about/</loc>
|
<loc>https://kst4contest.hamradioonline.de/screenshots/</loc>
|
||||||
<lastmod>2026-07-06</lastmod>
|
<lastmod>2026-07-06</lastmod>
|
||||||
</url>
|
</url>
|
||||||
<url>
|
<url>
|
||||||
<loc>https://kst4contest.hamradioonline.de/news/2026-07-website-launch/</loc>
|
<loc>https://kst4contest.hamradioonline.de/news/2026-07-website-launch/</loc>
|
||||||
<lastmod>2026-07-07</lastmod>
|
<lastmod>2026-07-07</lastmod>
|
||||||
</url>
|
</url>
|
||||||
|
<url>
|
||||||
|
<loc>https://kst4contest.hamradioonline.de/about/</loc>
|
||||||
|
<lastmod>2026-07-07</lastmod>
|
||||||
|
</url>
|
||||||
|
<url>
|
||||||
|
<loc>https://kst4contest.hamradioonline.de/contact/</loc>
|
||||||
|
<lastmod>2026-07-07</lastmod>
|
||||||
|
</url>
|
||||||
|
<url>
|
||||||
|
<loc>https://kst4contest.hamradioonline.de/legal-notice/</loc>
|
||||||
|
<lastmod>2026-07-07</lastmod>
|
||||||
|
</url>
|
||||||
|
<url>
|
||||||
|
<loc>https://kst4contest.hamradioonline.de/privacy/</loc>
|
||||||
|
<lastmod>2026-07-07</lastmod>
|
||||||
|
</url>
|
||||||
|
<url>
|
||||||
|
<loc>https://kst4contest.hamradioonline.de/</loc>
|
||||||
|
<lastmod>2026-07-07</lastmod>
|
||||||
|
</url>
|
||||||
|
<url>
|
||||||
|
<loc>https://kst4contest.hamradioonline.de/download/</loc>
|
||||||
|
<lastmod>2026-07-07</lastmod>
|
||||||
|
</url>
|
||||||
</urlset>
|
</urlset>
|
||||||
-16
@@ -1,16 +0,0 @@
|
|||||||
#!/bin/sh
|
|
||||||
basedir=$(dirname "$(echo "$0" | sed -e 's,\\,/,g')")
|
|
||||||
|
|
||||||
case `uname` in
|
|
||||||
*CYGWIN*|*MINGW*|*MSYS*)
|
|
||||||
if command -v cygpath > /dev/null 2>&1; then
|
|
||||||
basedir=`cygpath -w "$basedir"`
|
|
||||||
fi
|
|
||||||
;;
|
|
||||||
esac
|
|
||||||
|
|
||||||
if [ -x "$basedir/node" ]; then
|
|
||||||
exec "$basedir/node" "$basedir/../acorn/bin/acorn" "$@"
|
|
||||||
else
|
|
||||||
exec node "$basedir/../acorn/bin/acorn" "$@"
|
|
||||||
fi
|
|
||||||
-17
@@ -1,17 +0,0 @@
|
|||||||
@ECHO off
|
|
||||||
GOTO start
|
|
||||||
:find_dp0
|
|
||||||
SET dp0=%~dp0
|
|
||||||
EXIT /b
|
|
||||||
:start
|
|
||||||
SETLOCAL
|
|
||||||
CALL :find_dp0
|
|
||||||
|
|
||||||
IF EXIST "%dp0%\node.exe" (
|
|
||||||
SET "_prog=%dp0%\node.exe"
|
|
||||||
) ELSE (
|
|
||||||
SET "_prog=node"
|
|
||||||
SET PATHEXT=%PATHEXT:;.JS;=;%
|
|
||||||
)
|
|
||||||
|
|
||||||
endLocal & goto #_undefined_# 2>NUL || title %COMSPEC% & "%_prog%" "%dp0%\..\acorn\bin\acorn" %*
|
|
||||||
-28
@@ -1,28 +0,0 @@
|
|||||||
#!/usr/bin/env pwsh
|
|
||||||
$basedir=Split-Path $MyInvocation.MyCommand.Definition -Parent
|
|
||||||
|
|
||||||
$exe=""
|
|
||||||
if ($PSVersionTable.PSVersion -lt "6.0" -or $IsWindows) {
|
|
||||||
# Fix case when both the Windows and Linux builds of Node
|
|
||||||
# are installed in the same directory
|
|
||||||
$exe=".exe"
|
|
||||||
}
|
|
||||||
$ret=0
|
|
||||||
if (Test-Path "$basedir/node$exe") {
|
|
||||||
# Support pipeline input
|
|
||||||
if ($MyInvocation.ExpectingInput) {
|
|
||||||
$input | & "$basedir/node$exe" "$basedir/../acorn/bin/acorn" $args
|
|
||||||
} else {
|
|
||||||
& "$basedir/node$exe" "$basedir/../acorn/bin/acorn" $args
|
|
||||||
}
|
|
||||||
$ret=$LASTEXITCODE
|
|
||||||
} else {
|
|
||||||
# Support pipeline input
|
|
||||||
if ($MyInvocation.ExpectingInput) {
|
|
||||||
$input | & "node$exe" "$basedir/../acorn/bin/acorn" $args
|
|
||||||
} else {
|
|
||||||
& "node$exe" "$basedir/../acorn/bin/acorn" $args
|
|
||||||
}
|
|
||||||
$ret=$LASTEXITCODE
|
|
||||||
}
|
|
||||||
exit $ret
|
|
||||||
-16
@@ -1,16 +0,0 @@
|
|||||||
#!/bin/sh
|
|
||||||
basedir=$(dirname "$(echo "$0" | sed -e 's,\\,/,g')")
|
|
||||||
|
|
||||||
case `uname` in
|
|
||||||
*CYGWIN*|*MINGW*|*MSYS*)
|
|
||||||
if command -v cygpath > /dev/null 2>&1; then
|
|
||||||
basedir=`cygpath -w "$basedir"`
|
|
||||||
fi
|
|
||||||
;;
|
|
||||||
esac
|
|
||||||
|
|
||||||
if [ -x "$basedir/node" ]; then
|
|
||||||
exec "$basedir/node" "$basedir/../@11ty/eleventy/cmd.cjs" "$@"
|
|
||||||
else
|
|
||||||
exec node "$basedir/../@11ty/eleventy/cmd.cjs" "$@"
|
|
||||||
fi
|
|
||||||
-16
@@ -1,16 +0,0 @@
|
|||||||
#!/bin/sh
|
|
||||||
basedir=$(dirname "$(echo "$0" | sed -e 's,\\,/,g')")
|
|
||||||
|
|
||||||
case `uname` in
|
|
||||||
*CYGWIN*|*MINGW*|*MSYS*)
|
|
||||||
if command -v cygpath > /dev/null 2>&1; then
|
|
||||||
basedir=`cygpath -w "$basedir"`
|
|
||||||
fi
|
|
||||||
;;
|
|
||||||
esac
|
|
||||||
|
|
||||||
if [ -x "$basedir/node" ]; then
|
|
||||||
exec "$basedir/node" "$basedir/../@11ty/eleventy-dev-server/cmd.js" "$@"
|
|
||||||
else
|
|
||||||
exec node "$basedir/../@11ty/eleventy-dev-server/cmd.js" "$@"
|
|
||||||
fi
|
|
||||||
-17
@@ -1,17 +0,0 @@
|
|||||||
@ECHO off
|
|
||||||
GOTO start
|
|
||||||
:find_dp0
|
|
||||||
SET dp0=%~dp0
|
|
||||||
EXIT /b
|
|
||||||
:start
|
|
||||||
SETLOCAL
|
|
||||||
CALL :find_dp0
|
|
||||||
|
|
||||||
IF EXIST "%dp0%\node.exe" (
|
|
||||||
SET "_prog=%dp0%\node.exe"
|
|
||||||
) ELSE (
|
|
||||||
SET "_prog=node"
|
|
||||||
SET PATHEXT=%PATHEXT:;.JS;=;%
|
|
||||||
)
|
|
||||||
|
|
||||||
endLocal & goto #_undefined_# 2>NUL || title %COMSPEC% & "%_prog%" "%dp0%\..\@11ty\eleventy-dev-server\cmd.js" %*
|
|
||||||
-28
@@ -1,28 +0,0 @@
|
|||||||
#!/usr/bin/env pwsh
|
|
||||||
$basedir=Split-Path $MyInvocation.MyCommand.Definition -Parent
|
|
||||||
|
|
||||||
$exe=""
|
|
||||||
if ($PSVersionTable.PSVersion -lt "6.0" -or $IsWindows) {
|
|
||||||
# Fix case when both the Windows and Linux builds of Node
|
|
||||||
# are installed in the same directory
|
|
||||||
$exe=".exe"
|
|
||||||
}
|
|
||||||
$ret=0
|
|
||||||
if (Test-Path "$basedir/node$exe") {
|
|
||||||
# Support pipeline input
|
|
||||||
if ($MyInvocation.ExpectingInput) {
|
|
||||||
$input | & "$basedir/node$exe" "$basedir/../@11ty/eleventy-dev-server/cmd.js" $args
|
|
||||||
} else {
|
|
||||||
& "$basedir/node$exe" "$basedir/../@11ty/eleventy-dev-server/cmd.js" $args
|
|
||||||
}
|
|
||||||
$ret=$LASTEXITCODE
|
|
||||||
} else {
|
|
||||||
# Support pipeline input
|
|
||||||
if ($MyInvocation.ExpectingInput) {
|
|
||||||
$input | & "node$exe" "$basedir/../@11ty/eleventy-dev-server/cmd.js" $args
|
|
||||||
} else {
|
|
||||||
& "node$exe" "$basedir/../@11ty/eleventy-dev-server/cmd.js" $args
|
|
||||||
}
|
|
||||||
$ret=$LASTEXITCODE
|
|
||||||
}
|
|
||||||
exit $ret
|
|
||||||
-17
@@ -1,17 +0,0 @@
|
|||||||
@ECHO off
|
|
||||||
GOTO start
|
|
||||||
:find_dp0
|
|
||||||
SET dp0=%~dp0
|
|
||||||
EXIT /b
|
|
||||||
:start
|
|
||||||
SETLOCAL
|
|
||||||
CALL :find_dp0
|
|
||||||
|
|
||||||
IF EXIST "%dp0%\node.exe" (
|
|
||||||
SET "_prog=%dp0%\node.exe"
|
|
||||||
) ELSE (
|
|
||||||
SET "_prog=node"
|
|
||||||
SET PATHEXT=%PATHEXT:;.JS;=;%
|
|
||||||
)
|
|
||||||
|
|
||||||
endLocal & goto #_undefined_# 2>NUL || title %COMSPEC% & "%_prog%" "%dp0%\..\@11ty\eleventy\cmd.cjs" %*
|
|
||||||
-28
@@ -1,28 +0,0 @@
|
|||||||
#!/usr/bin/env pwsh
|
|
||||||
$basedir=Split-Path $MyInvocation.MyCommand.Definition -Parent
|
|
||||||
|
|
||||||
$exe=""
|
|
||||||
if ($PSVersionTable.PSVersion -lt "6.0" -or $IsWindows) {
|
|
||||||
# Fix case when both the Windows and Linux builds of Node
|
|
||||||
# are installed in the same directory
|
|
||||||
$exe=".exe"
|
|
||||||
}
|
|
||||||
$ret=0
|
|
||||||
if (Test-Path "$basedir/node$exe") {
|
|
||||||
# Support pipeline input
|
|
||||||
if ($MyInvocation.ExpectingInput) {
|
|
||||||
$input | & "$basedir/node$exe" "$basedir/../@11ty/eleventy/cmd.cjs" $args
|
|
||||||
} else {
|
|
||||||
& "$basedir/node$exe" "$basedir/../@11ty/eleventy/cmd.cjs" $args
|
|
||||||
}
|
|
||||||
$ret=$LASTEXITCODE
|
|
||||||
} else {
|
|
||||||
# Support pipeline input
|
|
||||||
if ($MyInvocation.ExpectingInput) {
|
|
||||||
$input | & "node$exe" "$basedir/../@11ty/eleventy/cmd.cjs" $args
|
|
||||||
} else {
|
|
||||||
& "node$exe" "$basedir/../@11ty/eleventy/cmd.cjs" $args
|
|
||||||
}
|
|
||||||
$ret=$LASTEXITCODE
|
|
||||||
}
|
|
||||||
exit $ret
|
|
||||||
-16
@@ -1,16 +0,0 @@
|
|||||||
#!/bin/sh
|
|
||||||
basedir=$(dirname "$(echo "$0" | sed -e 's,\\,/,g')")
|
|
||||||
|
|
||||||
case `uname` in
|
|
||||||
*CYGWIN*|*MINGW*|*MSYS*)
|
|
||||||
if command -v cygpath > /dev/null 2>&1; then
|
|
||||||
basedir=`cygpath -w "$basedir"`
|
|
||||||
fi
|
|
||||||
;;
|
|
||||||
esac
|
|
||||||
|
|
||||||
if [ -x "$basedir/node" ]; then
|
|
||||||
exec "$basedir/node" "$basedir/../errno/cli.js" "$@"
|
|
||||||
else
|
|
||||||
exec node "$basedir/../errno/cli.js" "$@"
|
|
||||||
fi
|
|
||||||
-17
@@ -1,17 +0,0 @@
|
|||||||
@ECHO off
|
|
||||||
GOTO start
|
|
||||||
:find_dp0
|
|
||||||
SET dp0=%~dp0
|
|
||||||
EXIT /b
|
|
||||||
:start
|
|
||||||
SETLOCAL
|
|
||||||
CALL :find_dp0
|
|
||||||
|
|
||||||
IF EXIST "%dp0%\node.exe" (
|
|
||||||
SET "_prog=%dp0%\node.exe"
|
|
||||||
) ELSE (
|
|
||||||
SET "_prog=node"
|
|
||||||
SET PATHEXT=%PATHEXT:;.JS;=;%
|
|
||||||
)
|
|
||||||
|
|
||||||
endLocal & goto #_undefined_# 2>NUL || title %COMSPEC% & "%_prog%" "%dp0%\..\errno\cli.js" %*
|
|
||||||
-28
@@ -1,28 +0,0 @@
|
|||||||
#!/usr/bin/env pwsh
|
|
||||||
$basedir=Split-Path $MyInvocation.MyCommand.Definition -Parent
|
|
||||||
|
|
||||||
$exe=""
|
|
||||||
if ($PSVersionTable.PSVersion -lt "6.0" -or $IsWindows) {
|
|
||||||
# Fix case when both the Windows and Linux builds of Node
|
|
||||||
# are installed in the same directory
|
|
||||||
$exe=".exe"
|
|
||||||
}
|
|
||||||
$ret=0
|
|
||||||
if (Test-Path "$basedir/node$exe") {
|
|
||||||
# Support pipeline input
|
|
||||||
if ($MyInvocation.ExpectingInput) {
|
|
||||||
$input | & "$basedir/node$exe" "$basedir/../errno/cli.js" $args
|
|
||||||
} else {
|
|
||||||
& "$basedir/node$exe" "$basedir/../errno/cli.js" $args
|
|
||||||
}
|
|
||||||
$ret=$LASTEXITCODE
|
|
||||||
} else {
|
|
||||||
# Support pipeline input
|
|
||||||
if ($MyInvocation.ExpectingInput) {
|
|
||||||
$input | & "node$exe" "$basedir/../errno/cli.js" $args
|
|
||||||
} else {
|
|
||||||
& "node$exe" "$basedir/../errno/cli.js" $args
|
|
||||||
}
|
|
||||||
$ret=$LASTEXITCODE
|
|
||||||
}
|
|
||||||
exit $ret
|
|
||||||
-16
@@ -1,16 +0,0 @@
|
|||||||
#!/bin/sh
|
|
||||||
basedir=$(dirname "$(echo "$0" | sed -e 's,\\,/,g')")
|
|
||||||
|
|
||||||
case `uname` in
|
|
||||||
*CYGWIN*|*MINGW*|*MSYS*)
|
|
||||||
if command -v cygpath > /dev/null 2>&1; then
|
|
||||||
basedir=`cygpath -w "$basedir"`
|
|
||||||
fi
|
|
||||||
;;
|
|
||||||
esac
|
|
||||||
|
|
||||||
if [ -x "$basedir/node" ]; then
|
|
||||||
exec "$basedir/node" "$basedir/../esprima/bin/esparse.js" "$@"
|
|
||||||
else
|
|
||||||
exec node "$basedir/../esprima/bin/esparse.js" "$@"
|
|
||||||
fi
|
|
||||||
-17
@@ -1,17 +0,0 @@
|
|||||||
@ECHO off
|
|
||||||
GOTO start
|
|
||||||
:find_dp0
|
|
||||||
SET dp0=%~dp0
|
|
||||||
EXIT /b
|
|
||||||
:start
|
|
||||||
SETLOCAL
|
|
||||||
CALL :find_dp0
|
|
||||||
|
|
||||||
IF EXIST "%dp0%\node.exe" (
|
|
||||||
SET "_prog=%dp0%\node.exe"
|
|
||||||
) ELSE (
|
|
||||||
SET "_prog=node"
|
|
||||||
SET PATHEXT=%PATHEXT:;.JS;=;%
|
|
||||||
)
|
|
||||||
|
|
||||||
endLocal & goto #_undefined_# 2>NUL || title %COMSPEC% & "%_prog%" "%dp0%\..\esprima\bin\esparse.js" %*
|
|
||||||
-28
@@ -1,28 +0,0 @@
|
|||||||
#!/usr/bin/env pwsh
|
|
||||||
$basedir=Split-Path $MyInvocation.MyCommand.Definition -Parent
|
|
||||||
|
|
||||||
$exe=""
|
|
||||||
if ($PSVersionTable.PSVersion -lt "6.0" -or $IsWindows) {
|
|
||||||
# Fix case when both the Windows and Linux builds of Node
|
|
||||||
# are installed in the same directory
|
|
||||||
$exe=".exe"
|
|
||||||
}
|
|
||||||
$ret=0
|
|
||||||
if (Test-Path "$basedir/node$exe") {
|
|
||||||
# Support pipeline input
|
|
||||||
if ($MyInvocation.ExpectingInput) {
|
|
||||||
$input | & "$basedir/node$exe" "$basedir/../esprima/bin/esparse.js" $args
|
|
||||||
} else {
|
|
||||||
& "$basedir/node$exe" "$basedir/../esprima/bin/esparse.js" $args
|
|
||||||
}
|
|
||||||
$ret=$LASTEXITCODE
|
|
||||||
} else {
|
|
||||||
# Support pipeline input
|
|
||||||
if ($MyInvocation.ExpectingInput) {
|
|
||||||
$input | & "node$exe" "$basedir/../esprima/bin/esparse.js" $args
|
|
||||||
} else {
|
|
||||||
& "node$exe" "$basedir/../esprima/bin/esparse.js" $args
|
|
||||||
}
|
|
||||||
$ret=$LASTEXITCODE
|
|
||||||
}
|
|
||||||
exit $ret
|
|
||||||
-16
@@ -1,16 +0,0 @@
|
|||||||
#!/bin/sh
|
|
||||||
basedir=$(dirname "$(echo "$0" | sed -e 's,\\,/,g')")
|
|
||||||
|
|
||||||
case `uname` in
|
|
||||||
*CYGWIN*|*MINGW*|*MSYS*)
|
|
||||||
if command -v cygpath > /dev/null 2>&1; then
|
|
||||||
basedir=`cygpath -w "$basedir"`
|
|
||||||
fi
|
|
||||||
;;
|
|
||||||
esac
|
|
||||||
|
|
||||||
if [ -x "$basedir/node" ]; then
|
|
||||||
exec "$basedir/node" "$basedir/../esprima/bin/esvalidate.js" "$@"
|
|
||||||
else
|
|
||||||
exec node "$basedir/../esprima/bin/esvalidate.js" "$@"
|
|
||||||
fi
|
|
||||||
-17
@@ -1,17 +0,0 @@
|
|||||||
@ECHO off
|
|
||||||
GOTO start
|
|
||||||
:find_dp0
|
|
||||||
SET dp0=%~dp0
|
|
||||||
EXIT /b
|
|
||||||
:start
|
|
||||||
SETLOCAL
|
|
||||||
CALL :find_dp0
|
|
||||||
|
|
||||||
IF EXIST "%dp0%\node.exe" (
|
|
||||||
SET "_prog=%dp0%\node.exe"
|
|
||||||
) ELSE (
|
|
||||||
SET "_prog=node"
|
|
||||||
SET PATHEXT=%PATHEXT:;.JS;=;%
|
|
||||||
)
|
|
||||||
|
|
||||||
endLocal & goto #_undefined_# 2>NUL || title %COMSPEC% & "%_prog%" "%dp0%\..\esprima\bin\esvalidate.js" %*
|
|
||||||
-28
@@ -1,28 +0,0 @@
|
|||||||
#!/usr/bin/env pwsh
|
|
||||||
$basedir=Split-Path $MyInvocation.MyCommand.Definition -Parent
|
|
||||||
|
|
||||||
$exe=""
|
|
||||||
if ($PSVersionTable.PSVersion -lt "6.0" -or $IsWindows) {
|
|
||||||
# Fix case when both the Windows and Linux builds of Node
|
|
||||||
# are installed in the same directory
|
|
||||||
$exe=".exe"
|
|
||||||
}
|
|
||||||
$ret=0
|
|
||||||
if (Test-Path "$basedir/node$exe") {
|
|
||||||
# Support pipeline input
|
|
||||||
if ($MyInvocation.ExpectingInput) {
|
|
||||||
$input | & "$basedir/node$exe" "$basedir/../esprima/bin/esvalidate.js" $args
|
|
||||||
} else {
|
|
||||||
& "$basedir/node$exe" "$basedir/../esprima/bin/esvalidate.js" $args
|
|
||||||
}
|
|
||||||
$ret=$LASTEXITCODE
|
|
||||||
} else {
|
|
||||||
# Support pipeline input
|
|
||||||
if ($MyInvocation.ExpectingInput) {
|
|
||||||
$input | & "node$exe" "$basedir/../esprima/bin/esvalidate.js" $args
|
|
||||||
} else {
|
|
||||||
& "node$exe" "$basedir/../esprima/bin/esvalidate.js" $args
|
|
||||||
}
|
|
||||||
$ret=$LASTEXITCODE
|
|
||||||
}
|
|
||||||
exit $ret
|
|
||||||
-16
@@ -1,16 +0,0 @@
|
|||||||
#!/bin/sh
|
|
||||||
basedir=$(dirname "$(echo "$0" | sed -e 's,\\,/,g')")
|
|
||||||
|
|
||||||
case `uname` in
|
|
||||||
*CYGWIN*|*MINGW*|*MSYS*)
|
|
||||||
if command -v cygpath > /dev/null 2>&1; then
|
|
||||||
basedir=`cygpath -w "$basedir"`
|
|
||||||
fi
|
|
||||||
;;
|
|
||||||
esac
|
|
||||||
|
|
||||||
if [ -x "$basedir/node" ]; then
|
|
||||||
exec "$basedir/node" "$basedir/../js-yaml/bin/js-yaml.js" "$@"
|
|
||||||
else
|
|
||||||
exec node "$basedir/../js-yaml/bin/js-yaml.js" "$@"
|
|
||||||
fi
|
|
||||||
-17
@@ -1,17 +0,0 @@
|
|||||||
@ECHO off
|
|
||||||
GOTO start
|
|
||||||
:find_dp0
|
|
||||||
SET dp0=%~dp0
|
|
||||||
EXIT /b
|
|
||||||
:start
|
|
||||||
SETLOCAL
|
|
||||||
CALL :find_dp0
|
|
||||||
|
|
||||||
IF EXIST "%dp0%\node.exe" (
|
|
||||||
SET "_prog=%dp0%\node.exe"
|
|
||||||
) ELSE (
|
|
||||||
SET "_prog=node"
|
|
||||||
SET PATHEXT=%PATHEXT:;.JS;=;%
|
|
||||||
)
|
|
||||||
|
|
||||||
endLocal & goto #_undefined_# 2>NUL || title %COMSPEC% & "%_prog%" "%dp0%\..\js-yaml\bin\js-yaml.js" %*
|
|
||||||
-28
@@ -1,28 +0,0 @@
|
|||||||
#!/usr/bin/env pwsh
|
|
||||||
$basedir=Split-Path $MyInvocation.MyCommand.Definition -Parent
|
|
||||||
|
|
||||||
$exe=""
|
|
||||||
if ($PSVersionTable.PSVersion -lt "6.0" -or $IsWindows) {
|
|
||||||
# Fix case when both the Windows and Linux builds of Node
|
|
||||||
# are installed in the same directory
|
|
||||||
$exe=".exe"
|
|
||||||
}
|
|
||||||
$ret=0
|
|
||||||
if (Test-Path "$basedir/node$exe") {
|
|
||||||
# Support pipeline input
|
|
||||||
if ($MyInvocation.ExpectingInput) {
|
|
||||||
$input | & "$basedir/node$exe" "$basedir/../js-yaml/bin/js-yaml.js" $args
|
|
||||||
} else {
|
|
||||||
& "$basedir/node$exe" "$basedir/../js-yaml/bin/js-yaml.js" $args
|
|
||||||
}
|
|
||||||
$ret=$LASTEXITCODE
|
|
||||||
} else {
|
|
||||||
# Support pipeline input
|
|
||||||
if ($MyInvocation.ExpectingInput) {
|
|
||||||
$input | & "node$exe" "$basedir/../js-yaml/bin/js-yaml.js" $args
|
|
||||||
} else {
|
|
||||||
& "node$exe" "$basedir/../js-yaml/bin/js-yaml.js" $args
|
|
||||||
}
|
|
||||||
$ret=$LASTEXITCODE
|
|
||||||
}
|
|
||||||
exit $ret
|
|
||||||
-16
@@ -1,16 +0,0 @@
|
|||||||
#!/bin/sh
|
|
||||||
basedir=$(dirname "$(echo "$0" | sed -e 's,\\,/,g')")
|
|
||||||
|
|
||||||
case `uname` in
|
|
||||||
*CYGWIN*|*MINGW*|*MSYS*)
|
|
||||||
if command -v cygpath > /dev/null 2>&1; then
|
|
||||||
basedir=`cygpath -w "$basedir"`
|
|
||||||
fi
|
|
||||||
;;
|
|
||||||
esac
|
|
||||||
|
|
||||||
if [ -x "$basedir/node" ]; then
|
|
||||||
exec "$basedir/node" "$basedir/../liquidjs/bin/liquid.js" "$@"
|
|
||||||
else
|
|
||||||
exec node "$basedir/../liquidjs/bin/liquid.js" "$@"
|
|
||||||
fi
|
|
||||||
-17
@@ -1,17 +0,0 @@
|
|||||||
@ECHO off
|
|
||||||
GOTO start
|
|
||||||
:find_dp0
|
|
||||||
SET dp0=%~dp0
|
|
||||||
EXIT /b
|
|
||||||
:start
|
|
||||||
SETLOCAL
|
|
||||||
CALL :find_dp0
|
|
||||||
|
|
||||||
IF EXIST "%dp0%\node.exe" (
|
|
||||||
SET "_prog=%dp0%\node.exe"
|
|
||||||
) ELSE (
|
|
||||||
SET "_prog=node"
|
|
||||||
SET PATHEXT=%PATHEXT:;.JS;=;%
|
|
||||||
)
|
|
||||||
|
|
||||||
endLocal & goto #_undefined_# 2>NUL || title %COMSPEC% & "%_prog%" "%dp0%\..\liquidjs\bin\liquid.js" %*
|
|
||||||
-28
@@ -1,28 +0,0 @@
|
|||||||
#!/usr/bin/env pwsh
|
|
||||||
$basedir=Split-Path $MyInvocation.MyCommand.Definition -Parent
|
|
||||||
|
|
||||||
$exe=""
|
|
||||||
if ($PSVersionTable.PSVersion -lt "6.0" -or $IsWindows) {
|
|
||||||
# Fix case when both the Windows and Linux builds of Node
|
|
||||||
# are installed in the same directory
|
|
||||||
$exe=".exe"
|
|
||||||
}
|
|
||||||
$ret=0
|
|
||||||
if (Test-Path "$basedir/node$exe") {
|
|
||||||
# Support pipeline input
|
|
||||||
if ($MyInvocation.ExpectingInput) {
|
|
||||||
$input | & "$basedir/node$exe" "$basedir/../liquidjs/bin/liquid.js" $args
|
|
||||||
} else {
|
|
||||||
& "$basedir/node$exe" "$basedir/../liquidjs/bin/liquid.js" $args
|
|
||||||
}
|
|
||||||
$ret=$LASTEXITCODE
|
|
||||||
} else {
|
|
||||||
# Support pipeline input
|
|
||||||
if ($MyInvocation.ExpectingInput) {
|
|
||||||
$input | & "node$exe" "$basedir/../liquidjs/bin/liquid.js" $args
|
|
||||||
} else {
|
|
||||||
& "node$exe" "$basedir/../liquidjs/bin/liquid.js" $args
|
|
||||||
}
|
|
||||||
$ret=$LASTEXITCODE
|
|
||||||
}
|
|
||||||
exit $ret
|
|
||||||
-16
@@ -1,16 +0,0 @@
|
|||||||
#!/bin/sh
|
|
||||||
basedir=$(dirname "$(echo "$0" | sed -e 's,\\,/,g')")
|
|
||||||
|
|
||||||
case `uname` in
|
|
||||||
*CYGWIN*|*MINGW*|*MSYS*)
|
|
||||||
if command -v cygpath > /dev/null 2>&1; then
|
|
||||||
basedir=`cygpath -w "$basedir"`
|
|
||||||
fi
|
|
||||||
;;
|
|
||||||
esac
|
|
||||||
|
|
||||||
if [ -x "$basedir/node" ]; then
|
|
||||||
exec "$basedir/node" "$basedir/../liquidjs/bin/liquid.js" "$@"
|
|
||||||
else
|
|
||||||
exec node "$basedir/../liquidjs/bin/liquid.js" "$@"
|
|
||||||
fi
|
|
||||||
-17
@@ -1,17 +0,0 @@
|
|||||||
@ECHO off
|
|
||||||
GOTO start
|
|
||||||
:find_dp0
|
|
||||||
SET dp0=%~dp0
|
|
||||||
EXIT /b
|
|
||||||
:start
|
|
||||||
SETLOCAL
|
|
||||||
CALL :find_dp0
|
|
||||||
|
|
||||||
IF EXIST "%dp0%\node.exe" (
|
|
||||||
SET "_prog=%dp0%\node.exe"
|
|
||||||
) ELSE (
|
|
||||||
SET "_prog=node"
|
|
||||||
SET PATHEXT=%PATHEXT:;.JS;=;%
|
|
||||||
)
|
|
||||||
|
|
||||||
endLocal & goto #_undefined_# 2>NUL || title %COMSPEC% & "%_prog%" "%dp0%\..\liquidjs\bin\liquid.js" %*
|
|
||||||
-28
@@ -1,28 +0,0 @@
|
|||||||
#!/usr/bin/env pwsh
|
|
||||||
$basedir=Split-Path $MyInvocation.MyCommand.Definition -Parent
|
|
||||||
|
|
||||||
$exe=""
|
|
||||||
if ($PSVersionTable.PSVersion -lt "6.0" -or $IsWindows) {
|
|
||||||
# Fix case when both the Windows and Linux builds of Node
|
|
||||||
# are installed in the same directory
|
|
||||||
$exe=".exe"
|
|
||||||
}
|
|
||||||
$ret=0
|
|
||||||
if (Test-Path "$basedir/node$exe") {
|
|
||||||
# Support pipeline input
|
|
||||||
if ($MyInvocation.ExpectingInput) {
|
|
||||||
$input | & "$basedir/node$exe" "$basedir/../liquidjs/bin/liquid.js" $args
|
|
||||||
} else {
|
|
||||||
& "$basedir/node$exe" "$basedir/../liquidjs/bin/liquid.js" $args
|
|
||||||
}
|
|
||||||
$ret=$LASTEXITCODE
|
|
||||||
} else {
|
|
||||||
# Support pipeline input
|
|
||||||
if ($MyInvocation.ExpectingInput) {
|
|
||||||
$input | & "node$exe" "$basedir/../liquidjs/bin/liquid.js" $args
|
|
||||||
} else {
|
|
||||||
& "node$exe" "$basedir/../liquidjs/bin/liquid.js" $args
|
|
||||||
}
|
|
||||||
$ret=$LASTEXITCODE
|
|
||||||
}
|
|
||||||
exit $ret
|
|
||||||
-16
@@ -1,16 +0,0 @@
|
|||||||
#!/bin/sh
|
|
||||||
basedir=$(dirname "$(echo "$0" | sed -e 's,\\,/,g')")
|
|
||||||
|
|
||||||
case `uname` in
|
|
||||||
*CYGWIN*|*MINGW*|*MSYS*)
|
|
||||||
if command -v cygpath > /dev/null 2>&1; then
|
|
||||||
basedir=`cygpath -w "$basedir"`
|
|
||||||
fi
|
|
||||||
;;
|
|
||||||
esac
|
|
||||||
|
|
||||||
if [ -x "$basedir/node" ]; then
|
|
||||||
exec "$basedir/node" "$basedir/../markdown-it/bin/markdown-it.mjs" "$@"
|
|
||||||
else
|
|
||||||
exec node "$basedir/../markdown-it/bin/markdown-it.mjs" "$@"
|
|
||||||
fi
|
|
||||||
-17
@@ -1,17 +0,0 @@
|
|||||||
@ECHO off
|
|
||||||
GOTO start
|
|
||||||
:find_dp0
|
|
||||||
SET dp0=%~dp0
|
|
||||||
EXIT /b
|
|
||||||
:start
|
|
||||||
SETLOCAL
|
|
||||||
CALL :find_dp0
|
|
||||||
|
|
||||||
IF EXIST "%dp0%\node.exe" (
|
|
||||||
SET "_prog=%dp0%\node.exe"
|
|
||||||
) ELSE (
|
|
||||||
SET "_prog=node"
|
|
||||||
SET PATHEXT=%PATHEXT:;.JS;=;%
|
|
||||||
)
|
|
||||||
|
|
||||||
endLocal & goto #_undefined_# 2>NUL || title %COMSPEC% & "%_prog%" "%dp0%\..\markdown-it\bin\markdown-it.mjs" %*
|
|
||||||
-28
@@ -1,28 +0,0 @@
|
|||||||
#!/usr/bin/env pwsh
|
|
||||||
$basedir=Split-Path $MyInvocation.MyCommand.Definition -Parent
|
|
||||||
|
|
||||||
$exe=""
|
|
||||||
if ($PSVersionTable.PSVersion -lt "6.0" -or $IsWindows) {
|
|
||||||
# Fix case when both the Windows and Linux builds of Node
|
|
||||||
# are installed in the same directory
|
|
||||||
$exe=".exe"
|
|
||||||
}
|
|
||||||
$ret=0
|
|
||||||
if (Test-Path "$basedir/node$exe") {
|
|
||||||
# Support pipeline input
|
|
||||||
if ($MyInvocation.ExpectingInput) {
|
|
||||||
$input | & "$basedir/node$exe" "$basedir/../markdown-it/bin/markdown-it.mjs" $args
|
|
||||||
} else {
|
|
||||||
& "$basedir/node$exe" "$basedir/../markdown-it/bin/markdown-it.mjs" $args
|
|
||||||
}
|
|
||||||
$ret=$LASTEXITCODE
|
|
||||||
} else {
|
|
||||||
# Support pipeline input
|
|
||||||
if ($MyInvocation.ExpectingInput) {
|
|
||||||
$input | & "node$exe" "$basedir/../markdown-it/bin/markdown-it.mjs" $args
|
|
||||||
} else {
|
|
||||||
& "node$exe" "$basedir/../markdown-it/bin/markdown-it.mjs" $args
|
|
||||||
}
|
|
||||||
$ret=$LASTEXITCODE
|
|
||||||
}
|
|
||||||
exit $ret
|
|
||||||
-16
@@ -1,16 +0,0 @@
|
|||||||
#!/bin/sh
|
|
||||||
basedir=$(dirname "$(echo "$0" | sed -e 's,\\,/,g')")
|
|
||||||
|
|
||||||
case `uname` in
|
|
||||||
*CYGWIN*|*MINGW*|*MSYS*)
|
|
||||||
if command -v cygpath > /dev/null 2>&1; then
|
|
||||||
basedir=`cygpath -w "$basedir"`
|
|
||||||
fi
|
|
||||||
;;
|
|
||||||
esac
|
|
||||||
|
|
||||||
if [ -x "$basedir/node" ]; then
|
|
||||||
exec "$basedir/node" "$basedir/../mime/cli.js" "$@"
|
|
||||||
else
|
|
||||||
exec node "$basedir/../mime/cli.js" "$@"
|
|
||||||
fi
|
|
||||||
-17
@@ -1,17 +0,0 @@
|
|||||||
@ECHO off
|
|
||||||
GOTO start
|
|
||||||
:find_dp0
|
|
||||||
SET dp0=%~dp0
|
|
||||||
EXIT /b
|
|
||||||
:start
|
|
||||||
SETLOCAL
|
|
||||||
CALL :find_dp0
|
|
||||||
|
|
||||||
IF EXIST "%dp0%\node.exe" (
|
|
||||||
SET "_prog=%dp0%\node.exe"
|
|
||||||
) ELSE (
|
|
||||||
SET "_prog=node"
|
|
||||||
SET PATHEXT=%PATHEXT:;.JS;=;%
|
|
||||||
)
|
|
||||||
|
|
||||||
endLocal & goto #_undefined_# 2>NUL || title %COMSPEC% & "%_prog%" "%dp0%\..\mime\cli.js" %*
|
|
||||||
-28
@@ -1,28 +0,0 @@
|
|||||||
#!/usr/bin/env pwsh
|
|
||||||
$basedir=Split-Path $MyInvocation.MyCommand.Definition -Parent
|
|
||||||
|
|
||||||
$exe=""
|
|
||||||
if ($PSVersionTable.PSVersion -lt "6.0" -or $IsWindows) {
|
|
||||||
# Fix case when both the Windows and Linux builds of Node
|
|
||||||
# are installed in the same directory
|
|
||||||
$exe=".exe"
|
|
||||||
}
|
|
||||||
$ret=0
|
|
||||||
if (Test-Path "$basedir/node$exe") {
|
|
||||||
# Support pipeline input
|
|
||||||
if ($MyInvocation.ExpectingInput) {
|
|
||||||
$input | & "$basedir/node$exe" "$basedir/../mime/cli.js" $args
|
|
||||||
} else {
|
|
||||||
& "$basedir/node$exe" "$basedir/../mime/cli.js" $args
|
|
||||||
}
|
|
||||||
$ret=$LASTEXITCODE
|
|
||||||
} else {
|
|
||||||
# Support pipeline input
|
|
||||||
if ($MyInvocation.ExpectingInput) {
|
|
||||||
$input | & "node$exe" "$basedir/../mime/cli.js" $args
|
|
||||||
} else {
|
|
||||||
& "node$exe" "$basedir/../mime/cli.js" $args
|
|
||||||
}
|
|
||||||
$ret=$LASTEXITCODE
|
|
||||||
}
|
|
||||||
exit $ret
|
|
||||||
-16
@@ -1,16 +0,0 @@
|
|||||||
#!/bin/sh
|
|
||||||
basedir=$(dirname "$(echo "$0" | sed -e 's,\\,/,g')")
|
|
||||||
|
|
||||||
case `uname` in
|
|
||||||
*CYGWIN*|*MINGW*|*MSYS*)
|
|
||||||
if command -v cygpath > /dev/null 2>&1; then
|
|
||||||
basedir=`cygpath -w "$basedir"`
|
|
||||||
fi
|
|
||||||
;;
|
|
||||||
esac
|
|
||||||
|
|
||||||
if [ -x "$basedir/node" ]; then
|
|
||||||
exec "$basedir/node" "$basedir/../nunjucks/bin/precompile" "$@"
|
|
||||||
else
|
|
||||||
exec node "$basedir/../nunjucks/bin/precompile" "$@"
|
|
||||||
fi
|
|
||||||
-17
@@ -1,17 +0,0 @@
|
|||||||
@ECHO off
|
|
||||||
GOTO start
|
|
||||||
:find_dp0
|
|
||||||
SET dp0=%~dp0
|
|
||||||
EXIT /b
|
|
||||||
:start
|
|
||||||
SETLOCAL
|
|
||||||
CALL :find_dp0
|
|
||||||
|
|
||||||
IF EXIST "%dp0%\node.exe" (
|
|
||||||
SET "_prog=%dp0%\node.exe"
|
|
||||||
) ELSE (
|
|
||||||
SET "_prog=node"
|
|
||||||
SET PATHEXT=%PATHEXT:;.JS;=;%
|
|
||||||
)
|
|
||||||
|
|
||||||
endLocal & goto #_undefined_# 2>NUL || title %COMSPEC% & "%_prog%" "%dp0%\..\nunjucks\bin\precompile" %*
|
|
||||||
-28
@@ -1,28 +0,0 @@
|
|||||||
#!/usr/bin/env pwsh
|
|
||||||
$basedir=Split-Path $MyInvocation.MyCommand.Definition -Parent
|
|
||||||
|
|
||||||
$exe=""
|
|
||||||
if ($PSVersionTable.PSVersion -lt "6.0" -or $IsWindows) {
|
|
||||||
# Fix case when both the Windows and Linux builds of Node
|
|
||||||
# are installed in the same directory
|
|
||||||
$exe=".exe"
|
|
||||||
}
|
|
||||||
$ret=0
|
|
||||||
if (Test-Path "$basedir/node$exe") {
|
|
||||||
# Support pipeline input
|
|
||||||
if ($MyInvocation.ExpectingInput) {
|
|
||||||
$input | & "$basedir/node$exe" "$basedir/../nunjucks/bin/precompile" $args
|
|
||||||
} else {
|
|
||||||
& "$basedir/node$exe" "$basedir/../nunjucks/bin/precompile" $args
|
|
||||||
}
|
|
||||||
$ret=$LASTEXITCODE
|
|
||||||
} else {
|
|
||||||
# Support pipeline input
|
|
||||||
if ($MyInvocation.ExpectingInput) {
|
|
||||||
$input | & "node$exe" "$basedir/../nunjucks/bin/precompile" $args
|
|
||||||
} else {
|
|
||||||
& "node$exe" "$basedir/../nunjucks/bin/precompile" $args
|
|
||||||
}
|
|
||||||
$ret=$LASTEXITCODE
|
|
||||||
}
|
|
||||||
exit $ret
|
|
||||||
-16
@@ -1,16 +0,0 @@
|
|||||||
#!/bin/sh
|
|
||||||
basedir=$(dirname "$(echo "$0" | sed -e 's,\\,/,g')")
|
|
||||||
|
|
||||||
case `uname` in
|
|
||||||
*CYGWIN*|*MINGW*|*MSYS*)
|
|
||||||
if command -v cygpath > /dev/null 2>&1; then
|
|
||||||
basedir=`cygpath -w "$basedir"`
|
|
||||||
fi
|
|
||||||
;;
|
|
||||||
esac
|
|
||||||
|
|
||||||
if [ -x "$basedir/node" ]; then
|
|
||||||
exec "$basedir/node" "$basedir/../semver/bin/semver.js" "$@"
|
|
||||||
else
|
|
||||||
exec node "$basedir/../semver/bin/semver.js" "$@"
|
|
||||||
fi
|
|
||||||
-17
@@ -1,17 +0,0 @@
|
|||||||
@ECHO off
|
|
||||||
GOTO start
|
|
||||||
:find_dp0
|
|
||||||
SET dp0=%~dp0
|
|
||||||
EXIT /b
|
|
||||||
:start
|
|
||||||
SETLOCAL
|
|
||||||
CALL :find_dp0
|
|
||||||
|
|
||||||
IF EXIST "%dp0%\node.exe" (
|
|
||||||
SET "_prog=%dp0%\node.exe"
|
|
||||||
) ELSE (
|
|
||||||
SET "_prog=node"
|
|
||||||
SET PATHEXT=%PATHEXT:;.JS;=;%
|
|
||||||
)
|
|
||||||
|
|
||||||
endLocal & goto #_undefined_# 2>NUL || title %COMSPEC% & "%_prog%" "%dp0%\..\semver\bin\semver.js" %*
|
|
||||||
-28
@@ -1,28 +0,0 @@
|
|||||||
#!/usr/bin/env pwsh
|
|
||||||
$basedir=Split-Path $MyInvocation.MyCommand.Definition -Parent
|
|
||||||
|
|
||||||
$exe=""
|
|
||||||
if ($PSVersionTable.PSVersion -lt "6.0" -or $IsWindows) {
|
|
||||||
# Fix case when both the Windows and Linux builds of Node
|
|
||||||
# are installed in the same directory
|
|
||||||
$exe=".exe"
|
|
||||||
}
|
|
||||||
$ret=0
|
|
||||||
if (Test-Path "$basedir/node$exe") {
|
|
||||||
# Support pipeline input
|
|
||||||
if ($MyInvocation.ExpectingInput) {
|
|
||||||
$input | & "$basedir/node$exe" "$basedir/../semver/bin/semver.js" $args
|
|
||||||
} else {
|
|
||||||
& "$basedir/node$exe" "$basedir/../semver/bin/semver.js" $args
|
|
||||||
}
|
|
||||||
$ret=$LASTEXITCODE
|
|
||||||
} else {
|
|
||||||
# Support pipeline input
|
|
||||||
if ($MyInvocation.ExpectingInput) {
|
|
||||||
$input | & "node$exe" "$basedir/../semver/bin/semver.js" $args
|
|
||||||
} else {
|
|
||||||
& "node$exe" "$basedir/../semver/bin/semver.js" $args
|
|
||||||
}
|
|
||||||
$ret=$LASTEXITCODE
|
|
||||||
}
|
|
||||||
exit $ret
|
|
||||||
-1692
File diff suppressed because it is too large
Load Diff
-21
@@ -1,21 +0,0 @@
|
|||||||
MIT License
|
|
||||||
|
|
||||||
Copyright (c) 2023 Zach Leatherman
|
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
||||||
of this software and associated documentation files (the "Software"), to deal
|
|
||||||
in the Software without restriction, including without limitation the rights
|
|
||||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
||||||
copies of the Software, and to permit persons to whom the Software is
|
|
||||||
furnished to do so, subject to the following conditions:
|
|
||||||
|
|
||||||
The above copyright notice and this permission notice shall be included in all
|
|
||||||
copies or substantial portions of the Software.
|
|
||||||
|
|
||||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
||||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
||||||
SOFTWARE.
|
|
||||||
-53
@@ -1,53 +0,0 @@
|
|||||||
# `dependency-tree-esm`
|
|
||||||
|
|
||||||
Returns an unordered array of local paths to dependencies of a Node ES module JavaScript file.
|
|
||||||
|
|
||||||
* See also: [`dependency-tree`](https://github.com/11ty/eleventy-dependency-tree) for the CommonJS version.
|
|
||||||
|
|
||||||
This is used by Eleventy to find dependencies of a JavaScript file to watch for changes to re-run Eleventy’s build.
|
|
||||||
|
|
||||||
## Installation
|
|
||||||
|
|
||||||
```
|
|
||||||
npm install --save-dev @11ty/dependency-tree-esm
|
|
||||||
```
|
|
||||||
|
|
||||||
## Features
|
|
||||||
|
|
||||||
* Ignores bare specifiers (e.g. `import "my-package"`)
|
|
||||||
* Ignores Node’s built-ins (e.g. `import "path"`)
|
|
||||||
* Handles circular dependencies
|
|
||||||
* Returns an empty set if the file does not exist.
|
|
||||||
|
|
||||||
## Usage
|
|
||||||
|
|
||||||
```js
|
|
||||||
// my-file.js
|
|
||||||
|
|
||||||
// if my-local-dependency.js has dependencies, it will include those too
|
|
||||||
import "./my-local-dependency.js";
|
|
||||||
|
|
||||||
|
|
||||||
// ignored, is a built-in
|
|
||||||
import path from "path";
|
|
||||||
```
|
|
||||||
|
|
||||||
```js
|
|
||||||
import { find } from "@11ty/dependency-tree-esm";
|
|
||||||
// CommonJS is fine too
|
|
||||||
// const { find } = require("@11ty/dependency-tree-esm");
|
|
||||||
|
|
||||||
await find("./my-file.js");
|
|
||||||
// returns ["./my-local-dependency.js"]
|
|
||||||
```
|
|
||||||
|
|
||||||
Return a [dependency-graph](https://github.com/jriecken/dependency-graph) instance:
|
|
||||||
|
|
||||||
```js
|
|
||||||
import { findGraph } from "@11ty/dependency-tree-esm";
|
|
||||||
// CommonJS is fine too
|
|
||||||
// const { find } = require("@11ty/dependency-tree-esm");
|
|
||||||
|
|
||||||
(await findGraph("./my-file.js")).overallOrder();
|
|
||||||
// returns ["./my-local-dependency.js", "./my-file.js"]
|
|
||||||
```
|
|
||||||
-173
@@ -1,173 +0,0 @@
|
|||||||
const path = require("node:path");
|
|
||||||
const { readFileSync, existsSync } = require("node:fs");
|
|
||||||
|
|
||||||
const acorn = require("acorn");
|
|
||||||
const normalizePath = require("normalize-path");
|
|
||||||
const { TemplatePath } = require("@11ty/eleventy-utils");
|
|
||||||
const { DepGraph } = require("dependency-graph");
|
|
||||||
|
|
||||||
// Is *not* a bare specifier (e.g. 'some-package')
|
|
||||||
// https://nodejs.org/dist/latest-v18.x/docs/api/esm.html#terminology
|
|
||||||
function isNonBareSpecifier(importSource) {
|
|
||||||
// Change \\ to / on Windows
|
|
||||||
let normalized = normalizePath(importSource);
|
|
||||||
// Relative specifier (e.g. './startup.js')
|
|
||||||
if(normalized.startsWith("./") || normalized.startsWith("../")) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
// Absolute specifier (e.g. 'file:///opt/nodejs/config.js')
|
|
||||||
if(normalized.startsWith("file:")) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
function normalizeFilePath(filePath) {
|
|
||||||
return TemplatePath.standardizeFilePath(path.relative(".", filePath));
|
|
||||||
}
|
|
||||||
|
|
||||||
function normalizeImportSourceToFilePath(filePath, source) {
|
|
||||||
let { dir } = path.parse(filePath);
|
|
||||||
let normalized = path.join(dir, source);
|
|
||||||
return normalizeFilePath(normalized);
|
|
||||||
}
|
|
||||||
|
|
||||||
function getImportAttributeType(attributes = []) {
|
|
||||||
for(let node of attributes) {
|
|
||||||
if(node.type === "ImportAttribute" && node.key.type === "Identifier" && node.key.name === "type") {
|
|
||||||
return node.value.value;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
async function getSources(filePath, contents, options = {}) {
|
|
||||||
let { parserOverride } = Object.assign({}, options);
|
|
||||||
let sources = new Set();
|
|
||||||
let sourcesToRecurse = new Set();
|
|
||||||
|
|
||||||
let ast = (parserOverride || acorn).parse(contents, {
|
|
||||||
sourceType: "module",
|
|
||||||
ecmaVersion: "latest",
|
|
||||||
});
|
|
||||||
|
|
||||||
for(let node of ast.body) {
|
|
||||||
if(node.type === "ImportDeclaration" && isNonBareSpecifier(node.source.value)) {
|
|
||||||
let importAttributeType = getImportAttributeType(node?.attributes);
|
|
||||||
let normalized = normalizeImportSourceToFilePath(filePath, node.source.value);
|
|
||||||
if(normalized !== filePath) {
|
|
||||||
sources.add(normalized);
|
|
||||||
|
|
||||||
// Recurse typeless (JavaScript) import types only
|
|
||||||
// Right now only `css` and `json` are valid but others might come later
|
|
||||||
if(!importAttributeType) {
|
|
||||||
sourcesToRecurse.add(normalized);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
return {
|
|
||||||
sources,
|
|
||||||
sourcesToRecurse,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// second argument used to be `alreadyParsedSet = new Set()`, keep that backwards compat
|
|
||||||
async function find(filePath, options = {}) {
|
|
||||||
if(options instanceof Set) {
|
|
||||||
options = {
|
|
||||||
alreadyParsedSet: options
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
if(!options.alreadyParsedSet) {
|
|
||||||
options.alreadyParsedSet = new Set();
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO add a cache here
|
|
||||||
// Unfortunately we need to read the entire file, imports need to be at the top level but they can be anywhere 🫠
|
|
||||||
let normalized = normalizeFilePath(filePath);
|
|
||||||
if(options.alreadyParsedSet.has(normalized) || !existsSync(filePath)) {
|
|
||||||
return [];
|
|
||||||
}
|
|
||||||
options.alreadyParsedSet.add(normalized);
|
|
||||||
|
|
||||||
let contents = readFileSync(normalized, { encoding: 'utf8' });
|
|
||||||
let { sources, sourcesToRecurse } = await getSources(filePath, contents, options);
|
|
||||||
|
|
||||||
// Recurse for nested deps
|
|
||||||
for(let source of sourcesToRecurse) {
|
|
||||||
let s = await find(source, options);
|
|
||||||
for(let p of s) {
|
|
||||||
if(sources.has(p) || p === filePath) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
sources.add(p);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return Array.from(sources);
|
|
||||||
}
|
|
||||||
|
|
||||||
function mergeGraphs(rootGraph, ...graphs) {
|
|
||||||
if(!(rootGraph instanceof DepGraph)) {
|
|
||||||
throw new Error("Incorrect type passed to mergeGraphs, expected DepGraph");
|
|
||||||
}
|
|
||||||
for(let g of graphs) {
|
|
||||||
for(let node of g.overallOrder()) {
|
|
||||||
if(!rootGraph.hasNode(node)) {
|
|
||||||
rootGraph.addNode(node);
|
|
||||||
}
|
|
||||||
for(let dep of g.directDependenciesOf(node)) {
|
|
||||||
rootGraph.addDependency(node, dep);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// second argument used to be `alreadyParsedSet = new Set()`, keep that backwards compat
|
|
||||||
async function findGraph(filePath, options = {}) {
|
|
||||||
if(options instanceof Set) {
|
|
||||||
options = {
|
|
||||||
alreadyParsedSet: options
|
|
||||||
};
|
|
||||||
}
|
|
||||||
if(!options.alreadyParsedSet) {
|
|
||||||
options.alreadyParsedSet = new Set();
|
|
||||||
}
|
|
||||||
|
|
||||||
let graph = new DepGraph();
|
|
||||||
let normalized = normalizeFilePath(filePath);
|
|
||||||
graph.addNode(filePath);
|
|
||||||
|
|
||||||
if(options.alreadyParsedSet.has(normalized) || !existsSync(filePath)) {
|
|
||||||
return graph;
|
|
||||||
}
|
|
||||||
options.alreadyParsedSet.add(normalized);
|
|
||||||
|
|
||||||
let contents = readFileSync(normalized, "utf8");
|
|
||||||
let { sources, sourcesToRecurse } = await getSources(filePath, contents, options);
|
|
||||||
for(let source of sources) {
|
|
||||||
if(!graph.hasNode(source)) {
|
|
||||||
graph.addNode(source);
|
|
||||||
}
|
|
||||||
graph.addDependency(normalized, source);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Recurse for nested deps
|
|
||||||
for(let source of sourcesToRecurse) {
|
|
||||||
let recursedGraph = await findGraph(source, options);
|
|
||||||
mergeGraphs(graph, recursedGraph);
|
|
||||||
}
|
|
||||||
|
|
||||||
return graph;
|
|
||||||
}
|
|
||||||
|
|
||||||
module.exports = {
|
|
||||||
find,
|
|
||||||
findGraph,
|
|
||||||
mergeGraphs,
|
|
||||||
};
|
|
||||||
-26
@@ -1,26 +0,0 @@
|
|||||||
{
|
|
||||||
"name": "@11ty/dependency-tree-esm",
|
|
||||||
"version": "2.0.4",
|
|
||||||
"description": "Finds all JavaScript ES Module dependencies from a filename.",
|
|
||||||
"main": "main.js",
|
|
||||||
"type": "commonjs",
|
|
||||||
"scripts": {
|
|
||||||
"test": "echo \"Error: run tests from root directory\" && exit 1"
|
|
||||||
},
|
|
||||||
"repository": {
|
|
||||||
"type": "git",
|
|
||||||
"url": "git+https://github.com/11ty/eleventy-utils.git"
|
|
||||||
},
|
|
||||||
"author": {
|
|
||||||
"name": "Zach Leatherman",
|
|
||||||
"email": "zach@zachleat.com",
|
|
||||||
"url": "https://zachleat.com/"
|
|
||||||
},
|
|
||||||
"license": "MIT",
|
|
||||||
"dependencies": {
|
|
||||||
"@11ty/eleventy-utils": "^2.0.7",
|
|
||||||
"acorn": "^8.15.0",
|
|
||||||
"dependency-graph": "^1.0.0",
|
|
||||||
"normalize-path": "^3.0.0"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
-21
@@ -1,21 +0,0 @@
|
|||||||
MIT License
|
|
||||||
|
|
||||||
Copyright (c) 2019 Zach Leatherman
|
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
||||||
of this software and associated documentation files (the "Software"), to deal
|
|
||||||
in the Software without restriction, including without limitation the rights
|
|
||||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
||||||
copies of the Software, and to permit persons to whom the Software is
|
|
||||||
furnished to do so, subject to the following conditions:
|
|
||||||
|
|
||||||
The above copyright notice and this permission notice shall be included in all
|
|
||||||
copies or substantial portions of the Software.
|
|
||||||
|
|
||||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
||||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
||||||
SOFTWARE.
|
|
||||||
-109
@@ -1,109 +0,0 @@
|
|||||||
# `@11ty/dependency-tree`
|
|
||||||
|
|
||||||
Returns an unordered array of local paths to dependencies of a CommonJS node JavaScript file (everything it or any of its dependencies `require`s).
|
|
||||||
|
|
||||||
* See also: [`@11ty/dependency-tree-esm`](https://github.com/11ty/eleventy-utils/tree/main/parse-deps-esm) for the ESM version.
|
|
||||||
* See also: [`@11ty/dependency-tree-typescript`](https://github.com/11ty/eleventy-utils/tree/main/parse-deps-typescript) for the TypeScript version.
|
|
||||||
|
|
||||||
Reduced feature (faster) alternative to the [`dependency-tree` package](https://www.npmjs.com/package/dependency-tree). This is used by Eleventy to find dependencies of a JavaScript file to watch for changes to re-run Eleventy’s build.
|
|
||||||
|
|
||||||
## Big Huge Caveat
|
|
||||||
|
|
||||||
⚠ A big caveat to this plugin is that it will require the file in order to build a dependency tree. So if your module has side effects and you don’t want it to execute—do not use this!
|
|
||||||
|
|
||||||
## Installation
|
|
||||||
|
|
||||||
```
|
|
||||||
npm install --save-dev @11ty/dependency-tree
|
|
||||||
```
|
|
||||||
|
|
||||||
## Features
|
|
||||||
|
|
||||||
* Ignores `node_modules`
|
|
||||||
* Or, use `nodeModuleNames` to control whether or not `node_modules` package names are included (added in v2.0.1)
|
|
||||||
* Ignores Node’s built-ins (e.g. `path`)
|
|
||||||
* Handles circular dependencies (Node does this too)
|
|
||||||
|
|
||||||
## Usage
|
|
||||||
|
|
||||||
```js
|
|
||||||
// my-file.js
|
|
||||||
|
|
||||||
// if my-local-dependency.js has dependencies, it will include those too
|
|
||||||
const test = require("./my-local-dependency.js");
|
|
||||||
|
|
||||||
// ignored, is a built-in
|
|
||||||
const path = require("path");
|
|
||||||
```
|
|
||||||
|
|
||||||
```js
|
|
||||||
const DependencyTree = require("@11ty/dependency-tree");
|
|
||||||
|
|
||||||
DependencyTree("./my-file.js");
|
|
||||||
// returns ["./my-local-dependency.js"]
|
|
||||||
```
|
|
||||||
|
|
||||||
### `allowNotFound`
|
|
||||||
|
|
||||||
```js
|
|
||||||
const DependencyTree = require("@11ty/dependency-tree");
|
|
||||||
|
|
||||||
DependencyTree("./this-does-not-exist.js"); // throws an error
|
|
||||||
|
|
||||||
DependencyTree("./this-does-not-exist.js", { allowNotFound: true });
|
|
||||||
// returns []
|
|
||||||
```
|
|
||||||
|
|
||||||
### `nodeModuleNames`
|
|
||||||
|
|
||||||
(Added in v2.0.1) Controls whether or not node package names are included in the list of dependencies.
|
|
||||||
|
|
||||||
* `nodeModuleNames: "include"`: included alongside the local JS files.
|
|
||||||
* `nodeModuleNames: "exclude"` (default): node module package names are excluded.
|
|
||||||
* `nodeModuleNames: "only"`: only node module package names are returned.
|
|
||||||
|
|
||||||
```js
|
|
||||||
// my-file.js:
|
|
||||||
|
|
||||||
require("./my-local-dependency.js");
|
|
||||||
require("@11ty/eleventy");
|
|
||||||
```
|
|
||||||
|
|
||||||
```js
|
|
||||||
const DependencyTree = require("@11ty/dependency-tree");
|
|
||||||
|
|
||||||
DependencyTree("./my-file.js");
|
|
||||||
// returns ["./my-local-dependency.js"]
|
|
||||||
|
|
||||||
DependencyTree("./my-file.js", { nodeModuleNames: "exclude" });
|
|
||||||
// returns ["./my-local-dependency.js"]
|
|
||||||
|
|
||||||
DependencyTree("./my-file.js", { nodeModuleNames: "include" });
|
|
||||||
// returns ["./my-local-dependency.js", "@11ty/eleventy"]
|
|
||||||
|
|
||||||
DependencyTree("./my-file.js", { nodeModuleNames: "only" });
|
|
||||||
// returns ["@11ty/eleventy"]
|
|
||||||
```
|
|
||||||
|
|
||||||
#### (Deprecated) `nodeModuleNamesOnly`
|
|
||||||
|
|
||||||
(Added in v2.0.0) Changed to use `nodeModuleNames` option instead. Backwards compatibility is maintained automatically.
|
|
||||||
|
|
||||||
* `nodeModuleNamesOnly: false` is mapped to `nodeModuleNames: "exclude"`
|
|
||||||
* `nodeModuleNamesOnly: true` is mapped to `nodeModuleNames: "only"`
|
|
||||||
|
|
||||||
If both `nodeModuleNamesOnly` and `nodeModuleNames` are included in options, `nodeModuleNames` takes precedence.
|
|
||||||
|
|
||||||
### `getPackagesByType` method
|
|
||||||
|
|
||||||
_Added in v4.0.2._
|
|
||||||
|
|
||||||
```js
|
|
||||||
const DependencyTree = require("@11ty/dependency-tree");
|
|
||||||
const {getPackagesByType} = DependencyTree;
|
|
||||||
|
|
||||||
// With `require(esm)` support, some targets may be modules!
|
|
||||||
// Return separate lists for commonjs and esm lists
|
|
||||||
getPackagesByType("./my-file.js");
|
|
||||||
// returns { commonjs: ["./my-file.js"], esm: [] }
|
|
||||||
```
|
|
||||||
-157
@@ -1,157 +0,0 @@
|
|||||||
const path = require("node:path");
|
|
||||||
const { TemplatePath } = require("@11ty/eleventy-utils");
|
|
||||||
|
|
||||||
function getAbsolutePath(filename) {
|
|
||||||
let normalizedFilename = path.normalize(filename); // removes dot slash
|
|
||||||
let hasDotSlash = filename.startsWith("./");
|
|
||||||
return hasDotSlash ? path.join(path.resolve("."), normalizedFilename) : normalizedFilename;
|
|
||||||
}
|
|
||||||
|
|
||||||
function getRelativePath(filename) {
|
|
||||||
let normalizedFilename = path.normalize(filename); // removes dot slash
|
|
||||||
let workingDirectory = path.resolve(".");
|
|
||||||
let result = "./" + (normalizedFilename.startsWith(workingDirectory) ? normalizedFilename.substr(workingDirectory.length + 1) : normalizedFilename);
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
function getNodeModuleName(filename) {
|
|
||||||
let foundNodeModules = false;
|
|
||||||
let moduleName = [];
|
|
||||||
|
|
||||||
let s = filename.split(path.sep);
|
|
||||||
for(let entry of s) {
|
|
||||||
if(entry === '.pnpm') {
|
|
||||||
foundNodeModules = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(foundNodeModules) {
|
|
||||||
moduleName.push(entry);
|
|
||||||
if(!entry.startsWith("@")) {
|
|
||||||
return moduleName.join("/");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if(entry === "node_modules") {
|
|
||||||
foundNodeModules = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* unordered */
|
|
||||||
function getDependenciesFor(filename, avoidCircular, optionsArg = {}) {
|
|
||||||
// backwards compatibility with `nodeModuleNamesOnly` boolean option
|
|
||||||
// Using `nodeModuleNames` property moving forward
|
|
||||||
if(("nodeModuleNamesOnly" in optionsArg) && !("nodeModuleNames" in optionsArg)) {
|
|
||||||
if(optionsArg.nodeModuleNamesOnly === true) {
|
|
||||||
optionsArg.nodeModuleNames = "only";
|
|
||||||
}
|
|
||||||
if(optionsArg.nodeModuleNamesOnly === false) {
|
|
||||||
optionsArg.nodeModuleNames = "exclude";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
let options = Object.assign({
|
|
||||||
allowNotFound: false,
|
|
||||||
nodeModuleNames: "exclude", // also "include" or "only"
|
|
||||||
}, optionsArg);
|
|
||||||
let absoluteFilename = getAbsolutePath(filename);
|
|
||||||
let modules = new Set();
|
|
||||||
|
|
||||||
try {
|
|
||||||
let res = require(absoluteFilename);
|
|
||||||
if(res[Symbol.toStringTag] === "Module" || res.__esModule) {
|
|
||||||
modules.add(filename);
|
|
||||||
}
|
|
||||||
} catch(e) {
|
|
||||||
if(e.code === "MODULE_NOT_FOUND" && options.allowNotFound) {
|
|
||||||
// do nothing
|
|
||||||
} else {
|
|
||||||
throw e;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
let mod;
|
|
||||||
for(let entry in require.cache) {
|
|
||||||
if(entry === absoluteFilename) {
|
|
||||||
mod = require.cache[entry];
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
let dependencies = new Set();
|
|
||||||
|
|
||||||
if(!mod) {
|
|
||||||
if(!options.allowNotFound) {
|
|
||||||
throw new Error(`Could not find ${filename} in @11ty/dependency-tree`);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
let relativeFilename = getRelativePath(mod.filename);
|
|
||||||
if(!avoidCircular) {
|
|
||||||
avoidCircular = {};
|
|
||||||
} else if(options.nodeModuleNames !== "only") {
|
|
||||||
dependencies.add(relativeFilename);
|
|
||||||
}
|
|
||||||
|
|
||||||
avoidCircular[relativeFilename] = true;
|
|
||||||
|
|
||||||
if(Array.isArray(mod.children) && mod.children.length > 0) {
|
|
||||||
for(let child of mod.children) {
|
|
||||||
let relativeChildFilename = getRelativePath(child.filename);
|
|
||||||
let nodeModuleName = getNodeModuleName(child.filename);
|
|
||||||
|
|
||||||
if(options.nodeModuleNames !== "exclude" && nodeModuleName) {
|
|
||||||
dependencies.add(nodeModuleName);
|
|
||||||
}
|
|
||||||
// Add dependencies of this dependency (not top level node_modules)
|
|
||||||
if(nodeModuleName === false) {
|
|
||||||
if(!dependencies.has(relativeChildFilename) && // avoid infinite looping with circular deps
|
|
||||||
!avoidCircular[relativeChildFilename] ) {
|
|
||||||
let { commonjs, esm } = getDependenciesFor(relativeChildFilename, avoidCircular, options);
|
|
||||||
for(let dependency of commonjs) {
|
|
||||||
dependencies.add(dependency);
|
|
||||||
}
|
|
||||||
for(let dependency of esm) {
|
|
||||||
modules.add(dependency);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return {
|
|
||||||
esm: modules,
|
|
||||||
commonjs: dependencies,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function normalizeList(packageSet) {
|
|
||||||
return Array.from( packageSet ).map(filePath => {
|
|
||||||
if(filePath.startsWith("./")) {
|
|
||||||
return TemplatePath.standardizeFilePath(filePath);
|
|
||||||
}
|
|
||||||
return filePath; // node_module name
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
function getCleanDependencyListFor(filename, options = {}) {
|
|
||||||
let { commonjs } = getDependenciesFor(filename, null, options);
|
|
||||||
|
|
||||||
return normalizeList(commonjs);
|
|
||||||
}
|
|
||||||
|
|
||||||
function getCleanDependencyListByTypeFor(filename, options = {}) {
|
|
||||||
let { commonjs, esm } = getDependenciesFor(filename, null, options);
|
|
||||||
|
|
||||||
return {
|
|
||||||
commonjs: normalizeList(commonjs),
|
|
||||||
esm: normalizeList(esm),
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
module.exports = getCleanDependencyListFor;
|
|
||||||
module.exports.getPackagesByType = getCleanDependencyListByTypeFor;
|
|
||||||
module.exports.getNodeModuleName = getNodeModuleName;
|
|
||||||
-42
@@ -1,42 +0,0 @@
|
|||||||
{
|
|
||||||
"name": "@11ty/dependency-tree",
|
|
||||||
"version": "4.0.2",
|
|
||||||
"description": "Finds all JavaScript CommmonJS require() dependencies from a filename.",
|
|
||||||
"main": "main.js",
|
|
||||||
"files": [
|
|
||||||
"main.js",
|
|
||||||
"!test",
|
|
||||||
"!test/**"
|
|
||||||
],
|
|
||||||
"scripts": {
|
|
||||||
"test": "npx ava"
|
|
||||||
},
|
|
||||||
"repository": {
|
|
||||||
"type": "git",
|
|
||||||
"url": "git+https://github.com/11ty/eleventy-dependency-tree.git"
|
|
||||||
},
|
|
||||||
"author": {
|
|
||||||
"name": "Zach Leatherman",
|
|
||||||
"email": "zach@zachleat.com",
|
|
||||||
"url": "https://zachleat.com/"
|
|
||||||
},
|
|
||||||
"license": "MIT",
|
|
||||||
"ava": {
|
|
||||||
"files": [
|
|
||||||
"./test/*.js"
|
|
||||||
],
|
|
||||||
"watchMode": {
|
|
||||||
"ignoreChanged": [
|
|
||||||
"./test/stubs/**"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"devDependencies": {
|
|
||||||
"@sindresorhus/is": "^4.6.0",
|
|
||||||
"ava": "^6.4.1",
|
|
||||||
"semver": "^7.7.3"
|
|
||||||
},
|
|
||||||
"dependencies": {
|
|
||||||
"@11ty/eleventy-utils": "^2.0.1"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
-60
@@ -1,60 +0,0 @@
|
|||||||
<p align="center"><img src="https://www.11ty.dev/img/logo-github.svg" width="200" height="200" alt="11ty Logo"></p>
|
|
||||||
|
|
||||||
# eleventy-dev-server 🕚⚡️🎈🐀
|
|
||||||
|
|
||||||
A minimal, modern, generic, hot-reloading local web server to help web developers.
|
|
||||||
|
|
||||||
## ➡ [Documentation](https://www.11ty.dev/docs/watch-serve/#eleventy-dev-server)
|
|
||||||
|
|
||||||
- Please star [Eleventy on GitHub](https://github.com/11ty/eleventy/)!
|
|
||||||
- Follow us on Twitter [@eleven_ty](https://twitter.com/eleven_ty)
|
|
||||||
- Support [11ty on Open Collective](https://opencollective.com/11ty)
|
|
||||||
- [11ty on npm](https://www.npmjs.com/org/11ty)
|
|
||||||
- [11ty on GitHub](https://github.com/11ty)
|
|
||||||
|
|
||||||
[](https://www.npmjs.com/package/@11ty/eleventy-dev-server)
|
|
||||||
|
|
||||||
## Installation
|
|
||||||
|
|
||||||
This is bundled with `@11ty/eleventy` (and you do not need to install it separately) in Eleventy v2.0.
|
|
||||||
|
|
||||||
## CLI
|
|
||||||
|
|
||||||
Eleventy Dev Server now also includes a CLI. The CLI is for **standalone** (non-Eleventy) use only: separate installation is unnecessary if you’re using this server with `@11ty/eleventy`.
|
|
||||||
|
|
||||||
```sh
|
|
||||||
npm install -g @11ty/eleventy-dev-server
|
|
||||||
|
|
||||||
# Alternatively, install locally into your project
|
|
||||||
npm install @11ty/eleventy-dev-server
|
|
||||||
```
|
|
||||||
|
|
||||||
This package requires Node 18 or newer.
|
|
||||||
|
|
||||||
### CLI Usage
|
|
||||||
|
|
||||||
```sh
|
|
||||||
# Serve the current directory
|
|
||||||
npx @11ty/eleventy-dev-server
|
|
||||||
|
|
||||||
# Serve a different subdirectory (also aliased as --input)
|
|
||||||
npx @11ty/eleventy-dev-server --dir=_site
|
|
||||||
|
|
||||||
# Disable the `domdiff` feature
|
|
||||||
npx @11ty/eleventy-dev-server --domdiff=false
|
|
||||||
|
|
||||||
# Full command list in the Help
|
|
||||||
npx @11ty/eleventy-dev-server --help
|
|
||||||
```
|
|
||||||
|
|
||||||
## Tests
|
|
||||||
|
|
||||||
```
|
|
||||||
npm run test
|
|
||||||
```
|
|
||||||
|
|
||||||
- We use the [ava JavaScript test runner](https://github.com/avajs/ava) ([Assertions documentation](https://github.com/avajs/ava/blob/master/docs/03-assertions.md))
|
|
||||||
|
|
||||||
## Changelog
|
|
||||||
|
|
||||||
* `v2.0.0` bumps Node.js minimum to 18.
|
|
||||||
-89
@@ -1,89 +0,0 @@
|
|||||||
const pkg = require("./package.json");
|
|
||||||
const EleventyDevServer = require("./server.js");
|
|
||||||
|
|
||||||
const Logger = {
|
|
||||||
info: function(...args) {
|
|
||||||
console.log( "[11ty/eleventy-dev-server]", ...args );
|
|
||||||
},
|
|
||||||
error: function(...args) {
|
|
||||||
console.error( "[11ty/eleventy-dev-server]", ...args );
|
|
||||||
},
|
|
||||||
fatal: function(...args) {
|
|
||||||
Logger.error(...args);
|
|
||||||
process.exitCode = 1;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
Logger.log = Logger.info;
|
|
||||||
|
|
||||||
class Cli {
|
|
||||||
static getVersion() {
|
|
||||||
return pkg.version;
|
|
||||||
}
|
|
||||||
|
|
||||||
static getHelp() {
|
|
||||||
return `Usage:
|
|
||||||
|
|
||||||
eleventy-dev-server
|
|
||||||
eleventy-dev-server --dir=_site
|
|
||||||
eleventy-dev-server --port=3000
|
|
||||||
|
|
||||||
Arguments:
|
|
||||||
|
|
||||||
--version
|
|
||||||
|
|
||||||
--dir=.
|
|
||||||
Directory to serve (default: \`.\`)
|
|
||||||
|
|
||||||
--input (alias for --dir)
|
|
||||||
|
|
||||||
--port=8080
|
|
||||||
Run the web server on this port (default: \`8080\`)
|
|
||||||
Will autoincrement if already in use.
|
|
||||||
|
|
||||||
--domdiff (enabled, default)
|
|
||||||
--domdiff=false (disabled)
|
|
||||||
Apply HTML changes without a full page reload.
|
|
||||||
|
|
||||||
--help`;
|
|
||||||
}
|
|
||||||
|
|
||||||
static getDefaultOptions() {
|
|
||||||
return {
|
|
||||||
port: "8080",
|
|
||||||
input: ".",
|
|
||||||
domDiff: true,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
async serve(options = {}) {
|
|
||||||
this.options = Object.assign(Cli.getDefaultOptions(), options);
|
|
||||||
|
|
||||||
this.server = EleventyDevServer.getServer("eleventy-dev-server-cli", this.options.input, {
|
|
||||||
// TODO allow server configuration extensions
|
|
||||||
showVersion: true,
|
|
||||||
logger: Logger,
|
|
||||||
domDiff: this.options.domDiff,
|
|
||||||
|
|
||||||
// CLI watches all files in the folder by default
|
|
||||||
// this is different from Eleventy usage!
|
|
||||||
watch: [ this.options.input ],
|
|
||||||
});
|
|
||||||
|
|
||||||
this.server.serve(this.options.port);
|
|
||||||
|
|
||||||
// TODO? send any errors here to the server too
|
|
||||||
// with server.sendError({ error });
|
|
||||||
}
|
|
||||||
|
|
||||||
close() {
|
|
||||||
if(this.server) {
|
|
||||||
return this.server.close();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
module.exports = {
|
|
||||||
Logger,
|
|
||||||
Cli
|
|
||||||
}
|
|
||||||
-336
@@ -1,336 +0,0 @@
|
|||||||
class Util {
|
|
||||||
static pad(num, digits = 2) {
|
|
||||||
let zeroes = new Array(digits + 1).join(0);
|
|
||||||
return `${zeroes}${num}`.slice(-1 * digits);
|
|
||||||
}
|
|
||||||
|
|
||||||
static log(message) {
|
|
||||||
Util.output("log", message);
|
|
||||||
}
|
|
||||||
static error(message, error) {
|
|
||||||
Util.output("error", message, error);
|
|
||||||
}
|
|
||||||
static output(type, ...messages) {
|
|
||||||
let now = new Date();
|
|
||||||
let date = `${Util.pad(now.getUTCHours())}:${Util.pad(
|
|
||||||
now.getUTCMinutes()
|
|
||||||
)}:${Util.pad(now.getUTCSeconds())}.${Util.pad(
|
|
||||||
now.getUTCMilliseconds(),
|
|
||||||
3
|
|
||||||
)}`;
|
|
||||||
console[type](`[11ty][${date} UTC]`, ...messages);
|
|
||||||
}
|
|
||||||
|
|
||||||
static capitalize(word) {
|
|
||||||
return word.substr(0, 1).toUpperCase() + word.substr(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
static matchRootAttributes(htmlContent) {
|
|
||||||
// Workaround for morphdom bug with attributes on <html> https://github.com/11ty/eleventy-dev-server/issues/6
|
|
||||||
// Note also `childrenOnly: true` above
|
|
||||||
const parser = new DOMParser();
|
|
||||||
let parsed = parser.parseFromString(htmlContent, "text/html");
|
|
||||||
let parsedDoc = parsed.documentElement;
|
|
||||||
let newAttrs = parsedDoc.getAttributeNames();
|
|
||||||
|
|
||||||
let docEl = document.documentElement;
|
|
||||||
// Remove old
|
|
||||||
let removedAttrs = docEl.getAttributeNames().filter(name => !newAttrs.includes(name));
|
|
||||||
for(let attr of removedAttrs) {
|
|
||||||
docEl.removeAttribute(attr);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Add new
|
|
||||||
for(let attr of newAttrs) {
|
|
||||||
docEl.setAttribute(attr, parsedDoc.getAttribute(attr));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static isEleventyLinkNodeMatch(from, to) {
|
|
||||||
// Issue #18 https://github.com/11ty/eleventy-dev-server/issues/18
|
|
||||||
// Don’t update a <link> if the _11ty searchParam is the only thing that’s different
|
|
||||||
if(from.tagName !== "LINK" || to.tagName !== "LINK") {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
let oldWithoutHref = from.cloneNode();
|
|
||||||
let newWithoutHref = to.cloneNode();
|
|
||||||
|
|
||||||
oldWithoutHref.removeAttribute("href");
|
|
||||||
newWithoutHref.removeAttribute("href");
|
|
||||||
|
|
||||||
// if all other attributes besides href match
|
|
||||||
if(!oldWithoutHref.isEqualNode(newWithoutHref)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
let oldUrl = new URL(from.href);
|
|
||||||
let newUrl = new URL(to.href);
|
|
||||||
|
|
||||||
// morphdom wants to force href="style.css?_11ty" => href="style.css"
|
|
||||||
let paramName = EleventyReload.QUERY_PARAM;
|
|
||||||
let isErasing = oldUrl.searchParams.has(paramName) && !newUrl.searchParams.has(paramName);
|
|
||||||
if(!isErasing) {
|
|
||||||
// not a match if _11ty has a new value (not being erased)
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
oldUrl.searchParams.set(paramName, "");
|
|
||||||
newUrl.searchParams.set(paramName, "");
|
|
||||||
|
|
||||||
// is a match if erasing and the rest of the href matches too
|
|
||||||
return oldUrl.toString() === newUrl.toString();
|
|
||||||
}
|
|
||||||
|
|
||||||
// https://github.com/patrick-steele-idem/morphdom/issues/178#issuecomment-652562769
|
|
||||||
static runScript(source, target) {
|
|
||||||
let script = document.createElement('script');
|
|
||||||
|
|
||||||
// copy over the attributes
|
|
||||||
for(let attr of [...source.attributes]) {
|
|
||||||
script.setAttribute(attr.nodeName ,attr.nodeValue);
|
|
||||||
}
|
|
||||||
|
|
||||||
script.innerHTML = source.innerHTML;
|
|
||||||
(target || source).replaceWith(script);
|
|
||||||
}
|
|
||||||
|
|
||||||
static fullPageReload() {
|
|
||||||
Util.log(`Page reload initiated.`);
|
|
||||||
window.location.reload();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
class EleventyReload {
|
|
||||||
static QUERY_PARAM = "_11ty";
|
|
||||||
|
|
||||||
static reloadTypes = {
|
|
||||||
css: (files, build = {}) => {
|
|
||||||
// Initiate a full page refresh if a CSS change is made but does match any stylesheet url
|
|
||||||
// `build.stylesheets` available in Eleventy v3.0.1-alpha.5+
|
|
||||||
if(Array.isArray(build.stylesheets)) {
|
|
||||||
let match = false;
|
|
||||||
for (let link of document.querySelectorAll(`link[rel="stylesheet"]`)) {
|
|
||||||
if (link.href) {
|
|
||||||
let url = new URL(link.href);
|
|
||||||
if(build.stylesheets.includes(url.pathname)) {
|
|
||||||
match = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if(!match) {
|
|
||||||
Util.fullPageReload();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for (let link of document.querySelectorAll(`link[rel="stylesheet"]`)) {
|
|
||||||
if (link.href) {
|
|
||||||
let url = new URL(link.href);
|
|
||||||
url.searchParams.set(this.QUERY_PARAM, Date.now());
|
|
||||||
link.href = url.toString();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Util.log(`CSS updated without page reload.`);
|
|
||||||
},
|
|
||||||
default: async (files, build = {}) => {
|
|
||||||
let morphed = false;
|
|
||||||
let domdiffTemplates = (build?.templates || []).filter(({url, inputPath}) => {
|
|
||||||
return url === document.location.pathname && (files || []).includes(inputPath);
|
|
||||||
});
|
|
||||||
|
|
||||||
if(domdiffTemplates.length === 0) {
|
|
||||||
Util.fullPageReload();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
// Important: using `./` allows the `.11ty` folder name to be changed
|
|
||||||
const { default: morphdom } = await import(`./morphdom.js`);
|
|
||||||
|
|
||||||
for (let {url, inputPath, content} of domdiffTemplates) {
|
|
||||||
// Notable limitation: this won’t re-run script elements or JavaScript page lifecycle events (load/DOMContentLoaded)
|
|
||||||
morphed = true;
|
|
||||||
|
|
||||||
morphdom(document.documentElement, content, {
|
|
||||||
childrenOnly: true,
|
|
||||||
onBeforeElUpdated: function (fromEl, toEl) {
|
|
||||||
if (fromEl.nodeName === "SCRIPT" && toEl.nodeName === "SCRIPT") {
|
|
||||||
if(toEl.innerHTML !== fromEl.innerHTML) {
|
|
||||||
Util.log(`JavaScript modified, reload initiated.`);
|
|
||||||
window.location.reload();
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Speed-up trick from morphdom docs
|
|
||||||
// https://dom.spec.whatwg.org/#concept-node-equals
|
|
||||||
if (fromEl.isEqualNode(toEl)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(Util.isEleventyLinkNodeMatch(fromEl, toEl)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
},
|
|
||||||
addChild: function(parent, child) {
|
|
||||||
// Declarative Shadow DOM https://github.com/11ty/eleventy-dev-server/issues/90
|
|
||||||
if(child.nodeName === "TEMPLATE" && child.hasAttribute("shadowrootmode")) {
|
|
||||||
let root = parent.shadowRoot;
|
|
||||||
if(root) {
|
|
||||||
// remove all shadow root children
|
|
||||||
while(root.firstChild) {
|
|
||||||
root.removeChild(root.firstChild);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
for(let newChild of child.content.childNodes) {
|
|
||||||
root.appendChild(newChild);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
parent.appendChild(child);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
onNodeAdded: function (node) {
|
|
||||||
if (node.nodeName === 'SCRIPT') {
|
|
||||||
Util.log(`JavaScript added, reload initiated.`);
|
|
||||||
window.location.reload();
|
|
||||||
}
|
|
||||||
},
|
|
||||||
onElUpdated: function(node) {
|
|
||||||
// Re-attach custom elements
|
|
||||||
if(customElements.get(node.tagName.toLowerCase())) {
|
|
||||||
let placeholder = document.createElement("div");
|
|
||||||
node.replaceWith(placeholder);
|
|
||||||
requestAnimationFrame(() => {
|
|
||||||
placeholder.replaceWith(node);
|
|
||||||
placeholder = undefined;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
Util.matchRootAttributes(content);
|
|
||||||
Util.log(`HTML delta applied without page reload.`);
|
|
||||||
}
|
|
||||||
} catch(e) {
|
|
||||||
Util.error( "Morphdom error", e );
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!morphed) {
|
|
||||||
Util.fullPageReload();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
constructor() {
|
|
||||||
this.connectionMessageShown = false;
|
|
||||||
this.reconnectEventCallback = this.reconnect.bind(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
init(options = {}) {
|
|
||||||
if (!("WebSocket" in window)) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
let documentUrl = new URL(document.location.href);
|
|
||||||
|
|
||||||
let reloadPort = new URL(import.meta.url).searchParams.get("reloadPort");
|
|
||||||
if(reloadPort) {
|
|
||||||
documentUrl.port = reloadPort;
|
|
||||||
}
|
|
||||||
|
|
||||||
let { protocol, host } = documentUrl;
|
|
||||||
|
|
||||||
// works with http (ws) and https (wss)
|
|
||||||
let websocketProtocol = protocol.replace("http", "ws");
|
|
||||||
|
|
||||||
let socket = new WebSocket(`${websocketProtocol}//${host}`);
|
|
||||||
|
|
||||||
socket.addEventListener("message", async (event) => {
|
|
||||||
try {
|
|
||||||
let data = JSON.parse(event.data);
|
|
||||||
// Util.log( JSON.stringify(data, null, 2) );
|
|
||||||
|
|
||||||
let { type } = data;
|
|
||||||
|
|
||||||
if (type === "eleventy.reload") {
|
|
||||||
await this.onreload(data);
|
|
||||||
} else if (type === "eleventy.msg") {
|
|
||||||
Util.log(`${data.message}`);
|
|
||||||
} else if (type === "eleventy.error") {
|
|
||||||
// Log Eleventy build errors
|
|
||||||
// Extra parsing for Node Error objects
|
|
||||||
let e = JSON.parse(data.error);
|
|
||||||
Util.error(`Build error: ${e.message}`, e);
|
|
||||||
} else if (type === "eleventy.status") {
|
|
||||||
// Full page reload on initial reconnect
|
|
||||||
if (data.status === "connected" && options.mode === "reconnect") {
|
|
||||||
window.location.reload();
|
|
||||||
}
|
|
||||||
|
|
||||||
if(data.status === "connected") {
|
|
||||||
// With multiple windows, only show one connection message
|
|
||||||
if(!this.isConnected) {
|
|
||||||
Util.log(Util.capitalize(data.status));
|
|
||||||
}
|
|
||||||
|
|
||||||
this.connectionMessageShown = true;
|
|
||||||
} else {
|
|
||||||
if(data.status === "disconnected") {
|
|
||||||
this.addReconnectListeners();
|
|
||||||
}
|
|
||||||
|
|
||||||
Util.log(Util.capitalize(data.status));
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
Util.log("Unknown event type", data);
|
|
||||||
}
|
|
||||||
} catch (e) {
|
|
||||||
Util.error(`Error parsing ${event.data}: ${e.message}`, e);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
socket.addEventListener("open", () => {
|
|
||||||
// no reconnection when the connect is already open
|
|
||||||
this.removeReconnectListeners();
|
|
||||||
});
|
|
||||||
|
|
||||||
socket.addEventListener("close", () => {
|
|
||||||
this.connectionMessageShown = false;
|
|
||||||
this.addReconnectListeners();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
reconnect() {
|
|
||||||
Util.log( "Reconnecting…" );
|
|
||||||
this.init({ mode: "reconnect" });
|
|
||||||
}
|
|
||||||
|
|
||||||
async onreload({ subtype, files, build }) {
|
|
||||||
if(!EleventyReload.reloadTypes[subtype]) {
|
|
||||||
subtype = "default";
|
|
||||||
}
|
|
||||||
|
|
||||||
await EleventyReload.reloadTypes[subtype](files, build);
|
|
||||||
}
|
|
||||||
|
|
||||||
addReconnectListeners() {
|
|
||||||
this.removeReconnectListeners();
|
|
||||||
|
|
||||||
window.addEventListener("focus", this.reconnectEventCallback);
|
|
||||||
window.addEventListener("visibilitychange", this.reconnectEventCallback);
|
|
||||||
}
|
|
||||||
|
|
||||||
removeReconnectListeners() {
|
|
||||||
window.removeEventListener("focus", this.reconnectEventCallback);
|
|
||||||
window.removeEventListener("visibilitychange", this.reconnectEventCallback);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
let reloader = new EleventyReload();
|
|
||||||
reloader.init();
|
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user