refactor: rename projects to opensource-projects

Frees /products/ for the product page and makes the open-source archive
explicit, rather than leaving two sections that both look like "projects".

- Move the directory in both locales and update the 18 internal links
  pointing into it.
- Rework helix for the GitHub layout: server/ and web/ are directories in
  a single repository there, not the two separate repositories Gitea had.
  The "fork both repositories" step and the section wording follow.
- Correct helix's stated Java version to 21, which is what the build
  actually targets.
This commit is contained in:
zihluwang committed 2026-09-25 14:48:38 +08:00
1 parent 29f7411da5
commit b2eb6b9638
30 files changed
+75 -71

No files matched your search

@@ -0,0 +1,390 @@
---
title: Calendar Toolbox API
---
## Package Overview
The library is organised under the base package `com.onixbyte.calendar` with the following structure:
| Package | Description |
|--------------------------------------------|--------------------------------------------|
| `com.onixbyte.calendar` | Root calendar object |
| `com.onixbyte.calendar.component` | iCalendar components (VEVENT, VTODO, etc.) |
| `com.onixbyte.calendar.component.property` | Component-level properties |
| `com.onixbyte.calendar.property` | Calendar-level properties |
| `com.onixbyte.calendar.parameter` | iCalendar property parameters |
| `com.onixbyte.calendar.recurrence` | Recurrence rule types |
| `com.onixbyte.calendar.value` | Value types |
| `com.onixbyte.calendar.util` | Formatting utilities |
---
## Calendar
The top-level object representing an iCalendar (RFC 5545) VCALENDAR container.
```java
Calendar calendar = Calendar.builder()
.withCalendarScale(...)
.withMethod(...)
.withProductIdentifier(...)
.withVersion(...)
.withOwner(...)
.withPrimaryCalendar(...)
.withPublishedTTL(...)
.withCalendarDescription(...)
.withCalendarName(...)
.withCalendarId(...)
.withCustomProperties(...)
.withComponents(event, todo, ...)
.build();
String icsContent = calendar.formatted();
```
### Calendar Properties
All calendar-level properties live in `com.onixbyte.calendar.property` and implement `CalendarProperty`.
| Class | iCalendar Property | Description |
|--------------------------|----------------------|-------------------------------------------|
| `CalendarScale` | `CALSCALE` | Calendar system (e.g., GREGORIAN) |
| `Method` | `METHOD` | iCalendar method (e.g., PUBLISH, REQUEST) |
| `ProductIdentifier` | `PRODID` | Product identifier of the calendar |
| `Version` | `VERSION` | iCalendar version (e.g., 2.0) |
| `Owner` | `X-OWNER` | Owner of the calendar |
| `PrimaryCalendar` | `X-PRIMARY-CALENDAR` | Whether this is a primary calendar |
| `PublishedTTL` | `X-PUBLISHED-TTL` | Time-to-live for published calendar |
| `CalendarDescription` | `X-CALENDAR-DESC` | Calendar description |
| `CalendarName` | `X-CALENDAR-NAME` | Calendar name |
| `CalendarId` | `X-CALENDAR-ID` | Calendar identifier |
| `CustomCalendarProperty` | `X-*` | Custom calendar properties |
Custom properties are created using a builder:
```java
var customProp = CustomCalendarProperty.builder()
.withParameters(...)
.build("X-MY-PROPERTY", "my-value");
```
> Note: Custom property names **must** start with `X-`.
---
## Components
Components represent the core entities in an iCalendar object. Each component implements `CalendarComponent` and is rendered between `BEGIN:TYPE` and `END:TYPE` delimiters.
### Event (VEVENT)
Represents a scheduled event.
```java
Event event = Event.builder()
.withDateTimeStamp(dtstamp) // required
.withUniqueIdentifier(uid) // required
.withDateTimeStart(dtstart)
.withDateTimeEnd(dtend) // mutually exclusive with duration
.withDuration(duration) // mutually exclusive with dtend
.withSummary(summary)
.withDescription(description)
.withClassification(classification)
.withDateTimeCreated(dateTimeCreated)
.withGeographicPosition(geoPos)
.withLastModified(lastModified)
.withLocation(location)
.withOrganiser(organiser)
.withPriority(priority)
.withSequenceNumber(seqNumber)
.withStatus(status)
.withTimeTransparency(transparency)
.withUniformResourceLocator(url)
.withRecurrenceId(recurrenceId)
.withRecurrenceRule(rrule)
.withAttachments(attachments)
.withAttendees(attendees)
.withCategories(categories)
.withComments(comments)
.withContacts(contacts)
.withExceptionDateTimes(exDates)
.withRequestStatuses(statuses)
.withRelated(related)
.withResources(resources)
.withRecurrenceDateTimes(rDates)
.build();
```
### Todo (VTODO)
Represents a to-do item or task.
```java
Todo todo = Todo.builder()
.withDateTimeStamp(dtstamp) // required
.withUniqueIdentifier(uid) // required
.withSummary(summary)
.withDateTimeStart(dtstart)
.withDateTimeDue(due) // mutually exclusive with duration
.withDuration(duration) // mutually exclusive with due
.withDateTimeCompleted(completed)
.withPercentComplete(percent)
.withClassification(classification)
.withDateTimeCreated(created)
.withDescription(description)
.withGeographicPosition(geoPos)
.withLastModified(lastModified)
.withLocation(location)
.withOrganiser(organiser)
.withPriority(priority)
.withSequenceNumber(seq)
.withStatus(status)
.withRecurrenceId(recurId)
.withRecurrenceRule(rrule)
.withUniformResourceLocator(url)
.withAttachments(attachments)
.withAttendees(attendees)
.withCategories(categories)
.withComments(comments)
.withContacts(contacts)
.withExceptionDateTimes(exDates)
.withRequestStatuses(statuses)
.withRelatedToList(related)
.withResources(resources)
.withRecurrenceDateTimes(rDates)
.build();
```
### Journal (VJOURNAL)
Represents a journal entry or diary note.
```java
Journal journal = Journal.builder()
.withDateTimeStamp(dtstamp) // required
.withUniqueIdentifier(uid) // required
.withSummary(summary)
.withClassification(classification)
.withDateTimeCreated(created)
.withDateTimeStart(dtstart)
.withLastModified(lastModified)
.withOrganiser(organiser)
.withRecurrenceId(recurId)
.withSequenceNumber(seq)
.withStatus(status)
.withUniformResourceLocator(url)
.withRecurrenceRule(rrule)
.withAttachments(attachments)
.withAttendees(attendees)
.withCategories(categories)
.withComments(comments)
.withContacts(contacts)
.withDescriptions(descriptions)
.withExceptionDateTimes(exDates)
.withRelatedToList(related)
.withRecurrenceDate(rDates)
.withRequestStatuses(statuses)
.build();
```
### FreeBusy (VFREEBUSY)
Represents free/busy time information.
```java
FreeBusy freeBusy = FreeBusy.builder()
.withDateTimeStamp(dtstamp) // required
.withUniqueIdentifier(uid) // required
.withContact(contact)
.withDateTimeStart(dtstart)
.withDateTimeEnd(dtend)
.withOrganiser(organiser)
.withUniformResourceLocator(url)
.withAttendees(attendees)
.withComments(comments)
.withFreeBusyTimes(freeBusyTimes)
.withRequestStatuses(statuses)
.build();
```
### TimeZone (VTIMEZONE)
Defines time zone rules including standard and daylight saving time transitions.
```java
TimeZone timezone = TimeZone.builder()
.withTimeZoneIdentifier(tzId)
.withLastModified(lastModified)
.withTimeZoneUrl(tzUrl)
.withTimeZoneProperties(standardProp, daylightProp)
.build();
```
Time zone properties define the actual transition rules:
```java
TimeZoneProperty standard = TimeZoneProperty.builder()
.withDateTimeStart(dtstart)
.withTimeZoneOffsetTo(offsetTo)
.withTimeZoneOffsetFrom(offsetFrom)
.withRecurrenceRule(rrule)
.withTimeZoneNames(tzName)
.buildStandard(); // or buildDaylight()
TimeZoneProperty daylight = TimeZoneProperty.builder()
.withDateTimeStart(dtstart)
.withTimeZoneOffsetTo(offsetTo)
.withTimeZoneOffsetFrom(offsetFrom)
.buildDaylight();
```
### Alarm (VALARM)
Defines alarm/reminder notifications. Three alarm types are supported:
```java
// Audio alarm
Alarm audioAlarm = Alarm.builder()
.withTrigger(trigger)
.withDuration(duration)
.withRepeatCount(repeatCount)
.withAttachments(audioAttachment)
.buildAudio();
// Display alarm
Alarm displayAlarm = Alarm.builder()
.withTrigger(trigger)
.withDescription(description) // required
.withDuration(duration)
.withRepeatCount(repeatCount)
.buildDisplay();
// Email alarm
Alarm emailAlarm = Alarm.builder()
.withTrigger(trigger)
.withDescription(description) // required
.withSummary(summary) // required
.withAttendees(attendees) // required
.withDuration(duration)
.withRepeatCount(repeatCount)
.buildEmail();
```
---
## Component Properties
Component properties live in `com.onixbyte.calendar.component.property` and implement `ComponentProperty`.
| Class | iCalendar Property | Description |
|---------------------------|--------------------|----------------------------------------------------------|
| `Action` | `ACTION` | Alarm action type (AUDIO, DISPLAY, EMAIL) |
| `Attachment` | `ATTACH` | Document attachment |
| `Attendee` | `ATTENDEE` | Event/task attendee |
| `Categories` | `CATEGORIES` | Categories or tags |
| `Classification` | `CLASS` | Access classification (PUBLIC, PRIVATE, CONFIDENTIAL) |
| `Comment` | `COMMENT` | Comment |
| `Contact` | `CONTACT` | Contact information |
| `DateTimeCompleted` | `COMPLETED` | Completion date-time |
| `DateTimeCreated` | `CREATED` | Creation date-time |
| `DateTimeDue` | `DUE` | Due date-time |
| `DateTimeEnd` | `DTEND` | End date-time |
| `DateTimeStamp` | `DTSTAMP` | Date-time stamp |
| `DateTimeStart` | `DTSTART` | Start date-time |
| `Description` | `DESCRIPTION` | Description |
| `ExceptionDateTimes` | `EXDATE` | Exception date-times |
| `FreeBusyTime` | `FREEBUSY` | Free/busy time periods |
| `GeographicPosition` | `GEO` | Geographic position (lat/long) |
| `LastModified` | `LAST-MODIFIED` | Last modified date-time |
| `Location` | `LOCATION` | Location |
| `Organiser` | `ORGANIZER` | Event organiser |
| `PercentComplete` | `PERCENT-COMPLETE` | Completion percentage |
| `Priority` | `PRIORITY` | Priority level |
| `RecurrenceDateTimes` | `RDATE` | Recurrence date-times |
| `RecurrenceId` | `RECURRENCE-ID` | Recurrence instance identifier |
| `RecurrenceRule` | `RRULE` | Recurrence rule |
| `RelatedTo` | `RELATED-TO` | Related component reference |
| `RepeatCount` | `REPEAT` | Alarm repeat count |
| `RequestStatus` | `REQUEST-STATUS` | Request status |
| `Resources` | `RESOURCES` | Resources |
| `SequenceNumber` | `SEQUENCE` | Sequence number (revision) |
| `Status` | `STATUS` | Component status (TENTATIVE, CONFIRMED, CANCELLED, etc.) |
| `Summary` | `SUMMARY` | Title or summary |
| `TimeTransparency` | `TRANSP` | Time transparency (OPAQUE, TRANSPARENT) |
| `TimeZoneIdentifier` | `TZID` | Time zone identifier |
| `TimeZoneName` | `TZNAME` | Time zone name |
| `TimeZoneOffsetFrom` | `TZOFFSETFROM` | Time zone offset from UTC |
| `TimeZoneOffsetTo` | `TZOFFSETTO` | Time zone offset to UTC |
| `TimeZoneUrl` | `TZURL` | Time zone URL |
| `Trigger` | `TRIGGER` | Alarm trigger |
| `UniformResourceLocator` | `URL` | Associated URL |
| `UniqueIdentifier` | `UID` | Unique identifier |
| `CustomComponentProperty` | `X-*` | Custom component properties |
---
## Parameters
Parameters in `com.onixbyte.calendar.parameter` provide additional qualifiers on component properties.
| Class | iCalendar Parameter | Description |
|-------------------------------|---------------------|--------------------------------------------------------|
| `AlarmTriggerRelationship` | `RELATED` | Trigger relationship (START, END) |
| `AlternateTextRepresentation` | `ALTREP` | Alternate text URI |
| `CalendarUserType` | `CUTYPE` | Calendar user type (INDIVIDUAL, GROUP, RESOURCE, etc.) |
| `CommonName` | `CN` | Common name |
| `Delegatees` | `DELEGATED-TO` | Delegatees |
| `Delegators` | `DELEGATED-FROM` | Delegators |
| `DirectoryEntryReference` | `DIR` | Directory entry URI |
| `FormatType` | `FMTTYPE` | Format type (MIME type) |
| `FreeBusyTimeType` | `FBTYPE` | Free/busy time type |
| `InlineEncoding` | `ENCODING` | Inline encoding (BASE64) |
| `Language` | `LANGUAGE` | Language |
| `Membership` | `MEMBER` | Group membership |
| `ParticipationRole` | `ROLE` | Participation role (CHAIR, REQ-PARTICIPANT, etc.) |
| `ParticipationStatus` | `PARTSTAT` | Participation status (ACCEPTED, DECLINED, etc.) |
| `RecurrenceIdentifierRange` | `RANGE` | Recurrence range (THISANDPRIOR, THISANDFUTURE) |
| `RelationshipType` | `RELTYPE` | Relationship type (PARENT, CHILD, SIBLING) |
| `RsvpExpectation` | `RSVP` | RSVP expectation (TRUE, FALSE) |
| `SentBy` | `SENT-BY` | Sent by |
| `TimeZoneIdentifier` | `TZID` | Time zone identifier |
| `ValueDataType` | `VALUE` | Value data type (DATE, DATE-TIME, etc.) |
---
## Recurrence Types
Located in `com.onixbyte.calendar.recurrence`.
| Class | Description |
|--------------|---------------------------------------------------------------------------|
| `Frequency` | Frequency constants (DAILY, WEEKLY, MONTHLY, YEARLY) for recurrence rules |
| `WeekdayNum` | Weekday number for recurrence rules (e.g., 2nd Monday) |
---
## Value Types
Located in `com.onixbyte.calendar.value`.
| Class | Description |
|---------------------|------------------------------------------------|
| `FreeBusyTimeValue` | Represents free/busy time value |
| `PeriodOfTime` | Represents a period of time with start and end |
| `PropertyValue` | Base value type for properties |
| `UtcOffset` | UTC offset value (e.g., `-05:00`, `+01:00`) |
---
## Formatted Output
All components and properties provide a `formatted()` method that returns an iCalendar-compliant string representation. The `Calendar.formatted()` method produces a complete `.ics` output wrapped in `BEGIN:VCALENDAR`/`END:VCALENDAR`.
```java
String ics = calendar.formatted();
// BEGIN:VCALENDAR
// CALSCALE:GREGORIAN
// METHOD:PUBLISH
// ...
// END:VCALENDAR
```
@@ -0,0 +1,102 @@
---
title: Calendar Toolbox
---
import { Tabs, Tab } from "@rspress/core/theme"
## Introduction
Calendar Toolbox is a Java library designed to simplify the creation of `.ics` files, adhering to the iCalendar specification (RFC 5545). This library provides developers with a straightforward API to generate calendar events that can be imported into popular calendar applications such as Microsoft Outlook, Google Calendar, and Apple Calendar.
With Calendar Toolbox, you can effortlessly create, customise, and export calendar event files programmatically, enabling integration of calendar functionalities into your Java applications with minimal effort.
## Features
- **Full RFC 5545 Compliance** — Supports standard iCalendar components including VEVENT, VTODO, VJOURNAL, VFREEBUSY, VTIMEZONE, and VALARM.
- **Fluent Builder Pattern** — All components and properties use builder pattern for readable and intuitive construction.
- **Type-Safe Properties** — Strongly typed properties and parameters ensure correctness at compile time.
- **Custom Extensions** — Support for custom `X-` properties at both calendar and component level.
- **Lightweight** — Zero external dependencies for core functionality.
## Installation
<Tabs>
<Tab label="Gradle with Kotlin DSL">
```kotlin title="build.gradle.kts"
dependencies {
implementation("com.onixbyte:calendar-toolbox:1.1.0")
}
```
</Tab>
<Tab label="Maven">
```xml title="pom.xml"
<dependencies>
<dependency>
<groupId>com.onixbyte</groupId>
<artifactId>calendar-toolbox</artifactId>
<version>1.1.0</version>
</dependency>
</dependencies>
```
</Tab>
</Tabs>
## Quick Start
```java
import com.onixbyte.calendar.Calendar;
import com.onixbyte.calendar.component.Event;
import com.onixbyte.calendar.component.property.*;
import com.onixbyte.calendar.property.*;
import java.time.LocalDateTime;
import java.time.ZoneOffset;
import java.time.ZonedDateTime;
public class CalendarExample {
public static void main(String[] args) {
// Create required date-time properties
var now = ZonedDateTime.now(ZoneOffset.UTC);
var dtstamp = DateTimeStamp.of(now);
var uid = UniqueIdentifier.of("meeting-001@example.com");
var dtstart = DateTimeStart.of(
LocalDateTime.of(2025, 8, 15, 9, 0),
"America/New_York"
);
var dtend = DateTimeEnd.of(
LocalDateTime.of(2025, 8, 15, 10, 0),
"America/New_York"
);
var summary = Summary.of("Team Standup");
var description = Description.of("Daily team standup meeting.");
// Build the event
var event = Event.builder()
.withDateTimeStamp(dtstamp)
.withUniqueIdentifier(uid)
.withDateTimeStart(dtstart)
.withDateTimeEnd(dtend)
.withSummary(summary)
.withDescription(description)
.build();
// Build the calendar and output .ics content
var calendar = Calendar.builder()
.withCalendarScale(CalendarScale.of("GREGORIAN"))
.withMethod(Method.of("PUBLISH"))
.withProductIdentifier(ProductIdentifier.of("-//OnixByte//Calendar Toolbox//EN"))
.withVersion(Version.of("2.0"))
.withComponents(event)
.build();
System.out.println(calendar.formatted());
}
}
```
This produces an `.ics` string that can be saved to a file or sent via email.
## License
Calendar Toolbox is open-source software released under the MIT License.
@@ -0,0 +1,248 @@
---
title: Captcha API
---
## Package Overview
The library is organised under the base package `com.onixbyte.captcha` with the following structure:
| Package | Description |
|---------------------------------------------|---------------------------------------|
| `com.onixbyte.captcha` | Core interfaces |
| `com.onixbyte.captcha.impl` | Default implementations |
| `com.onixbyte.captcha.text` | Text producer and renderer interfaces |
| `com.onixbyte.captcha.text.impl` | Text producer and renderer impls |
| `com.onixbyte.captcha.text.enums` | Text-related enums |
| `com.onixbyte.captcha.background` | Background producer interface |
| `com.onixbyte.captcha.background.impl` | Background producer implementations |
| `com.onixbyte.captcha.noise` | Noise producer interface |
| `com.onixbyte.captcha.noise.impl` | Noise producer implementations |
| `com.onixbyte.captcha.gimpy` | Distortion engine interface |
| `com.onixbyte.captcha.gimpy.impl` | Distortion engine implementations |
---
## Producer
The top-level interface responsible for creating CAPTCHA images with text drawn on them.
```java
Producer captcha = DefaultCaptchaProducer.builder()
.textProducer(textProducer)
.wordRenderer(wordRenderer)
.gimpyEngine(gimpyEngine)
.backgroundProducer(backgroundProducer)
.width(200)
.height(50)
.borderDrawn(true)
.borderColour(Color.BLACK)
.borderThickness(1)
.build();
String text = captcha.createText();
BufferedImage image = captcha.createImage(text);
```
### DefaultCaptchaProducer Builder
| Method | Default Value | Description |
|---------------------|---------------------------------------------|---------------------------------------|
| `textProducer` | `DefaultTextProducer.builder().build()` | The text producer to use |
| `wordRenderer` | `DefaultWordRenderer.builder().build()` | The word renderer to use |
| `gimpyEngine` | `WaterRipple.builder().build()` | The distortion engine to use |
| `backgroundProducer`| `DefaultBackgroundProducer.builder().build()`| The background producer to use |
| `width` | `200` | Width of the CAPTCHA image |
| `height` | `50` | Height of the CAPTCHA image |
| `borderDrawn` | `true` | Whether a border is drawn |
| `borderColour` | `Color.BLACK` | The colour of the border |
| `borderThickness` | `1` | The thickness of the border |
---
## Text
### TextProducer
Interface for creating CAPTCHA text strings.
```java
public interface TextProducer {
String getText();
}
```
#### DefaultTextProducer
Generates random text with configurable length and character set.
```java
DefaultTextProducer textProducer = DefaultTextProducer.builder()
.length(6) // default: 6
.chars("ABCDEFGHIJKLMNOPQRSTUVWXYZ".toCharArray()) // default: a-z, A-Z, 0-9
.build();
```
| Method | Default Value | Description |
|----------|-----------------------------------------------------------|--------------------------------|
| `length` | `6` | Length of generated text |
| `chars` | `a-z`, `A-Z`, `0-9` (62 characters) | Characters used for generation |
### WordRenderer
Interface for rendering text onto an image.
```java
public interface WordRenderer {
BufferedImage renderWord(String word, int width, int height);
}
```
#### DefaultWordRenderer
Renders text with configurable font, colour, and spacing.
```java
DefaultWordRenderer wordRenderer = DefaultWordRenderer.builder()
.fontSize(40) // default: 40
.fonts("Arial", "Courier") // default: Arial, Courier
.fontColour(Color.BLACK) // default: Color.BLACK
.charSpace(2) // default: 2
.fontStyle(FontStyle.BOLD) // default: FontStyle.BOLD
.build();
```
| Method | Default Value | Description |
|-------------|-----------------------------------|-----------------------------------------|
| `fontSize` | `40` | Font size in pixels |
| `fonts` | `["Arial", "Courier"]` | Font families to use (randomly chosen) |
| `fontColour`| `Color.BLACK` | Font colour |
| `charSpace` | `2` | Space between characters in pixels |
| `fontStyle` | `FontStyle.BOLD` | Font style to apply |
### FontStyle
Defines the supported font styles for rendering CAPTCHA text.
| Value | Corresponding AWT Constant | Description |
|---------------|-------------------------------------|------------------------------|
| `PLAIN` | `java.awt.Font.PLAIN` | Plain style |
| `BOLD` | `java.awt.Font.BOLD` | Bold style |
| `ITALIC` | `java.awt.Font.ITALIC` | Italic style |
| `BOLD_ITALIC` | `java.awt.Font.BOLD | Font.ITALIC` | Bold and italic combined |
---
## GimpyEngine
Interface for applying image distortion effects.
```java
public interface GimpyEngine {
BufferedImage getDistortedImage(BufferedImage baseImage);
}
```
### WaterRipple
Applies a water ripple distortion effect. Extends `AbstractGimpyEngine` and adds noise automatically.
```java
WaterRipple gimpy = WaterRipple.builder()
.noiseProducer(DefaultNoiseProducer.builder().build()) // default: DefaultNoiseProducer
.build();
```
| Method | Default Value | Description |
|-----------------|---------------------------------------------|------------------------------|
| `noiseProducer` | `DefaultNoiseProducer.builder().build()` | The noise producer to use |
### FishEyeGimpy
Applies a fish-eye distortion effect with horizontal and vertical lines over the image.
```java
FishEyeGimpy gimpy = FishEyeGimpy.builder()
.build();
```
### ShadowGimpy
Applies a shadow and ripple effect. Extends `AbstractGimpyEngine` and adds noise automatically.
```java
ShadowGimpy gimpy = ShadowGimpy.builder()
.noiseProducer(DefaultNoiseProducer.builder().build()) // default: DefaultNoiseProducer
.build();
```
| Method | Default Value | Description |
|-----------------|---------------------------------------------|------------------------------|
| `noiseProducer` | `DefaultNoiseProducer.builder().build()` | The noise producer to use |
---
## Noise
### NoiseProducer
Interface for adding noise to an image.
```java
public interface NoiseProducer {
void makeNoise(BufferedImage image, float factorOne, float factorTwo,
float factorThree, float factorFour);
}
```
#### DefaultNoiseProducer
Adds noise curves with configurable colour.
```java
DefaultNoiseProducer noise = DefaultNoiseProducer.builder()
.noiseColour(Color.BLACK) // default: Color.BLACK
.build();
```
| Method | Default Value | Description |
|---------------|---------------|---------------------|
| `noiseColour` | `Color.BLACK` | The noise colour |
#### NoNoiseProducer
A no-op implementation that does not add any noise to the image.
```java
NoiseProducer noise = NoNoiseProducer.builder()
.build();
```
---
## Background
### BackgroundProducer
Interface for adding background to an image.
```java
public interface BackgroundProducer {
BufferedImage addBackground(BufferedImage image);
}
```
#### DefaultBackgroundProducer
Creates a gradient background with configurable start and end colours.
```java
DefaultBackgroundProducer background = DefaultBackgroundProducer.builder()
.colourFrom(Color.WHITE) // default: Color.LIGHT_GRAY
.colourTo(Color.LIGHT_GRAY) // default: Color.WHITE
.build();
```
| Method | Default Value | Description |
|--------------|--------------------|---------------------------------|
| `colourFrom` | `Color.LIGHT_GRAY` | The starting colour of gradient |
| `colourTo` | `Color.WHITE` | The ending colour of gradient |
@@ -0,0 +1,89 @@
---
title: Captcha
---
import { Tabs, Tab } from "@rspress/core/theme"
## Introduction
Captcha is a Java library for generating CAPTCHA images. This project is a spiritual successor to Google's Kaptcha, modernised for contemporary development practices.
With Captcha, you can easily generate customisable CAPTCHA images with various distortion effects, noise, and background options to integrate into your Java applications.
## Features
- **Easy Integration** — Simple builder-based API for quick setup and configuration.
- **Customisable CAPTCHA Generation** — Configure text length, character sets, font styles, and colours.
- **Multiple Distortion Effects** — Choose from Water Ripple, Fish Eye, and Shadow effects.
- **Configurable Noise** — Add noise lines with custom colours, or disable noise entirely.
- **Gradient Backgrounds** — Customisable gradient background colours.
- **Clean, Modern Codebase** — Well-documented, type-safe, and easy to extend.
## Installation
<Tabs>
<Tab label="Gradle with Kotlin DSL">
```kotlin title="build.gradle.kts"
dependencies {
implementation("com.onixbyte:captcha:1.0.0")
}
```
</Tab>
<Tab label="Maven">
```xml title="pom.xml"
<dependencies>
<dependency>
<groupId>com.onixbyte</groupId>
<artifactId>captcha</artifactId>
<version>1.0.0</version>
</dependency>
</dependencies>
```
</Tab>
</Tabs>
## Quick Start
```java
import com.onixbyte.captcha.Producer;
import com.onixbyte.captcha.background.BackgroundProducer;
import com.onixbyte.captcha.background.impl.DefaultBackgroundProducer;
import com.onixbyte.captcha.gimpy.GimpyEngine;
import com.onixbyte.captcha.gimpy.impl.WaterRipple;
import com.onixbyte.captcha.impl.DefaultCaptchaProducer;
import com.onixbyte.captcha.noise.NoiseProducer;
import com.onixbyte.captcha.noise.impl.DefaultNoiseProducer;
import com.onixbyte.captcha.text.TextProducer;
import com.onixbyte.captcha.text.WordRenderer;
import com.onixbyte.captcha.text.impl.DefaultTextProducer;
import com.onixbyte.captcha.text.impl.DefaultWordRenderer;
import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
public class CaptchaExample {
public static void main(String[] args) throws IOException {
// Create a CAPTCHA producer with default configurations
Producer captcha = DefaultCaptchaProducer.builder().build();
// Generate text and create the image
String captchaText = captcha.createText();
BufferedImage captchaImage = captcha.createImage(captchaText);
// Save the image to a file
ImageIO.write(captchaImage, "png", new File("captcha.png"));
System.out.println("CAPTCHA text: " + captchaText);
}
}
```
This generates a CAPTCHA image with a 6-character random text and saves it as a PNG file.
## License
Captcha is open-source software released under the MIT License.
@@ -0,0 +1,216 @@
---
title: Claude Code Skills Manager
---
import { Tabs, Tab } from "@rspress/core/theme"
## Introduction
Claude Code Skills Manager (`ccsm`) is a CLI tool for discovering, installing, and managing Claude Code skills from Git-based marketplace repositories. It lets you register any public Git repository that exposes a `skills.json` manifest as a skill source, then search, install, update, and remove skills through a single command-line interface.
Skills are deployed directly into Claude Code's own skills directory (`~/.claude/skills/`), where Claude Code picks them up automatically at startup.
## Installation
<Tabs>
<Tab label="Pre-built binaries">
Download the latest binary for your platform from the [Releases page](https://onixbyte.dev/onixbyte/claude-code-skill-manager/releases).
| Platform | Binary |
|----------|--------|
| Linux (amd64) | `ccsm-linux-amd64` |
| macOS (amd64) | `ccsm-darwin-amd64` |
| Windows (amd64) | `ccsm-windows-amd64.exe` |
Place the binary somewhere on your `PATH` and rename it to `ccsm` (or `ccsm.exe` on Windows).
</Tab>
<Tab label="Cargo install">
```bash
git clone https://onixbyte.dev/onixbyte/claude-code-skill-manager.git
cd claude-code-skill-manager
cargo install --path .
```
Requires a Rust toolchain (install via [rustup.rs](https://rustup.rs)).
</Tab>
<Tab label="Build from source">
```bash
git clone https://onixbyte.dev/onixbyte/claude-code-skill-manager.git
cd claude-code-skill-manager
cargo build --release
```
The binary will be at `target/release/ccsm` (or `ccsm.exe` on Windows).
</Tab>
</Tabs>
## Quick Start
### Registering a marketplace
A marketplace is any public Git repository with a `skills.json` manifest at its root. Register one with:
```bash
ccsm marketplace add https://github.com/example/skills
```
CCSM fetches the manifest and caches it locally. You can register as many marketplaces as you need.
### Browsing and installing skills
```bash
# Search across all registered marketplaces
ccsm search
# Search with a keyword filter
ccsm search git
# Install a skill by name
ccsm install my-awesome-skill
# If the same name exists in multiple marketplaces, disambiguate
ccsm install my-skill --marketplace my-marketplace
```
### Managing installed skills
```bash
# List installed skills
ccsm list
# Show details about an installed skill
ccsm info my-awesome-skill
# Update all installed skills to their latest versions
ccsm update
# Update a specific skill
ccsm update my-awesome-skill
# Remove a skill
ccsm remove my-awesome-skill
```
### Marketplace management
```bash
# List all registered marketplaces
ccsm marketplace list
# Refresh cached manifests (all marketplaces)
ccsm marketplace update
# Refresh a specific marketplace
ccsm marketplace update my-marketplace
# Remove a marketplace
ccsm marketplace remove my-marketplace
```
### Install modes
CCSM supports two deploy modes:
| Mode | Behaviour | Use case |
|------|-----------|----------|
| `copy` (default) | Files are physically copied to `~/.claude/skills/<name>/` | Normal use — safe and self-contained |
| `link` | A symlink is created pointing to the local store | Skill development — changes to source files are picked up immediately |
Set the default mode in your config, or override per install:
```bash
ccsm install my-skill --link
```
## Creating Your Own Skill Marketplace
A marketplace is simply a public Git repository containing a `skills.json` manifest. There is no server component, no authentication, and no API key — CCSM reads the manifest directly from the Git forge's raw file endpoint.
### Marketplace repository structure
```
your-marketplace-repo/
skills.json # Required: the manifest
README.md # Optional
```
### The `skills.json` manifest
```json
{
"name": "My Marketplace",
"version": "1.0.0",
"skills": [
{
"name": "my-skill",
"description": "A short description shown in search results",
"repository": "https://github.com/user/skill-repo",
"branch": "main"
},
{
"name": "another-skill",
"description": "A skill that lives in a monorepo subdirectory",
"repository": "https://github.com/user/monorepo",
"branch": "main",
"path": "skills/another-skill"
}
]
}
```
**Top-level fields:**
| Field | Required | Description |
|-------|----------|-------------|
| `name` | Yes | Marketplace display name |
| `version` | No | Arbitrary version string for your own tracking |
| `skills` | No | Array of skill entries (defaults to `[]`) |
**Skill entry fields:**
| Field | Required | Description |
|-------|----------|-------------|
| `name` | Yes | Unique skill identifier (used with `ccsm install <name>`) |
| `description` | Yes | One-line summary shown in `ccsm search` output |
| `repository` | Yes | Public Git repository URL for the skill |
| `branch` | No | Git branch to install from (tries `main` first, falls back to `master`) |
| `path` | No | Subdirectory within the repository where the skill files live — enables monorepos hosting multiple skills |
### How it works
1. **Manifest fetching** — CCSM constructs a raw-file URL from the marketplace repository URL and fetches `skills.json` from either the `main` or `master` branch. This works with GitHub, Gitea, GitLab, and any Git forge that exposes raw file endpoints.
2. **Skill downloading** — When a user installs a skill, CCSM downloads the skill repository archive (ZIP or tar.gz) from the Git forge, extracts it, and deploys the files to `~/.claude/skills/<name>/`.
3. **Monorepo support** — If a skill entry specifies a `path`, CCSM navigates into that subdirectory after extraction before deploying, so a single repository can host multiple skills.
### What goes in a skill repository
Each skill repository is a standard Claude Code skill directory. At minimum it should contain a `SKILL.md` manifest file:
```
my-skill-repo/
SKILL.md # Claude Code skill manifest
script.py # Supporting files
templates/
template.txt
```
### Publishing steps
1. Create a **public** Git repository with a `skills.json` at the root, following the format above.
2. Push it.
3. Anyone can register it with `ccsm marketplace add <url>`.
## How CCSM Stores Data
| Path | Purpose |
|------|---------|
| `~/.claude/skills/` | Claude Code's skills directory — where skills are deployed |
| `~/.config/ccsm/config.json` | CCSM configuration (registered marketplaces, default mode) |
| `~/.config/ccsm/marketplaces/` | Cached marketplace manifests |
| `~/.config/ccsm/skills/` | Downloaded skill files (local store) |
On Windows, `~/.config/` resolves to `C:\Users\<user>\AppData\Roaming\`.
## Licence
Claude Code Skills Manager is open-source software released under the MIT Licence.
@@ -0,0 +1,91 @@
---
title: Delta Force Guide API
---
## Backend API Overview
The backend is a Spring Boot 3 application organised under the base package `com.onixbyte.deltaforceguide`:
| Package | Description |
|---------------------------------------------|-----------------------------------|
| `controller` | REST API endpoint controllers |
| `service` | Business logic layer |
| `repository` | MyBatis data access layer |
| `domain` | JPA entity and domain objects |
| `config` | Spring configuration (security, cache, etc.) |
| `properties` | Configuration property classes |
| `enumeration` | Enumerated types |
| `shared` | Shared utilities |
## API Endpoints
### Authentication
| Method | Path | Description | Auth |
|--------|-----------------------|--------------------------|------|
| `POST` | `/api/auth/login` | Log in with credentials | No |
| `POST` | `/api/auth/refresh` | Refresh access token | No |
| `GET` | `/api/auth/profile` | Get current user profile | Yes |
### Firearms
| Method | Path | Description |
|----------|-----------------------|--------------------------|
| `GET` | `/api/firearms` | List firearms (paginated, filterable by type) |
| `GET` | `/api/firearms/:id` | Get firearm by ID |
| `POST` | `/api/firearms` | Create a new firearm |
| `PUT` | `/api/firearms/:id` | Update an existing firearm |
| `DELETE` | `/api/firearms/:id` | Remove a firearm |
### Modifications
| Method | Path | Description |
|----------|-----------------------------------|--------------------------------|
| `GET` | `/api/modifications` | List modifications (paginated, filterable by firearm and tags) |
| `GET` | `/api/modifications/:id` | Get modification by ID |
| `POST` | `/api/modifications` | Create a modification |
| `POST` | `/api/modifications/batch` | Batch create modifications |
| `PUT` | `/api/modifications/:id` | Update a modification |
| `DELETE` | `/api/modifications/:id` | Remove a modification |
| `DELETE` | `/api/modifications/batch-delete` | Batch remove modifications |
### Tags
| Method | Path | Description |
|--------|-----------------------|-----------------------|
| `GET` | `/api/tags` | List all tags |
## Frontend Routes
| Path | Layout | Page | Description |
|---------------|-------------|-------------------|---------------------------------|
| `/` | Hero Layout | Firearms Browser | Home page — firearm list |
| `/firearms` | Hero Layout | Firearms Browser | Firearm detail and search |
| `/mod-codes` | Hero Layout | Modification Codes| Modification code library |
| `/legal` | Hero Layout | Legal | Legal and privacy information |
| `/login` | Empty Layout| Login | User authentication page |
## Frontend State Management
Redux Toolkit with Redux Persist manages:
- **Auth state** — Access tokens, refresh tokens, user profile
- **Settings state** — User preferences persisted to local storage
## API Client
The frontend uses a shared `WebClient` wrapper around Axios that handles:
- Base URL configuration (pointing to the backend API)
- JWT access token injection via request interceptors
- Automatic token refresh on 401 responses
## Infrastructure
| Component | Technology |
|---------------|-----------------------------|
| Database | PostgreSQL (with Flyway migrations) |
| Cache | Redis (session/token storage) |
| File Storage | AWS S3 (firearm images) |
| Containerisation | Docker |
| Deployment | Docker Compose behind Nginx |
@@ -0,0 +1,46 @@
---
title: Delta Force Guide
---
## Introduction
Delta Force Guide is a full-stack web application providing a searchable library of firearm modification codes for the game Delta Force. It consists of two components:
- **Web Frontend** — A React-based SPA for browsing, filtering, and copying modification codes.
- **Backend Server** — A Spring Boot REST API handling data persistence, authentication, and content management.
The live site is available at **[dfguide.onixbyte.cn](https://dfguide.onixbyte.cn)**.
## Features
- **Firearm Browser** — Browse a curated list of in-game firearms with detailed stats.
- **Modification Code Library** — Search and filter modification codes by weapon, mode, and tags.
- **One-Click Copy** — Copy modification codes directly from the interface.
- **Efficient Rendering** — Large lists rendered smoothly with window virtualisation.
- **Authentication** — User login with JWT-based auth and CAPTCHA verification.
- **Admin Panel** — Full CRUD operations for firearms and modification data.
- **Static-Friendly** — Frontend deployed as a static site with API proxy.
## Architecture
| Component | Tech Stack |
|---------------|---------------------------------------------------------------|
| **Frontend** | React 19, TypeScript, Tailwind CSS 4, Ant Design 6, React Router 7, Redux Toolkit, TanStack Virtual |
| **Backend** | Spring Boot 3, Java 21, PostgreSQL, MyBatis, Flyway, Redis |
| **Auth** | JWT (access + refresh tokens), CAPTCHA integration |
| **Storage** | AWS S3 for image uploads |
The frontend is a static site served by Vite, communicating with the Spring Boot REST API backend. Authentication uses JWT access and refresh tokens with Redis-backed refresh token management.
## Repositories
- [delta-force-guide-server](https://github.com/onixbyte/delta-force-guide-server) — Spring Boot backend
- [delta-force-guide-web](https://github.com/onixbyte/delta-force-guide-web) — React frontend
## Quick Links
- **Live Site:** [dfguide.onixbyte.cn](https://dfguide.onixbyte.cn)
## License
Delta Force Guide is open-source software released under the MIT Licence.
@@ -0,0 +1,73 @@
---
title: Helix
---
## Introduction
Helix is a full-stack enterprise application template designed to accelerate the development of production-grade business applications. It provides a pre-built foundation with all the essential features an enterprise application needs, allowing teams to focus on business logic rather than infrastructure.
The project consists of two components:
- **Helix Server** — A Spring Boot backend providing REST APIs, authentication, authorisation, and data management.
- **Helix Web** — A React-based SPA frontend with a modern UI, role-based routing, and enterprise identity integration.
Helix is intended to be used as a starting point. Fork or clone it and begin building your own domain-specific features on top of the ready-made foundation.
## Features
### Backend (Helix Server)
- **Authentication & Authorisation** — JWT-based access and refresh token flow with Spring Security. Supports Microsoft Entra ID (Azure AD) integration.
- **Role-Based Access Control** — Fine-grained permissions via roles, authorities, and menu-level access control.
- **User & Organisation Management** — Full CRUD for users, departments, positions, and roles.
- **Menu Management** — Hierarchical menu tree with configurable visibility per role.
- **Asset Management** — File uploads to AWS S3 with CDN-ready prefix handling.
- **Settings Management** — Typed application settings persisted to database.
- **Captcha Integration** — Image CAPTCHA verification for login and registration flows.
- **Redis Caching** — High-performance caching with configurable TTL and custom serialisers.
- **Data Access** — Hybrid persistence with Spring Data JPA and MyBatis.
- **Validation** — Bean Validation groups with custom validation constraints.
### Frontend (Helix Web)
- **Enterprise Identity** — Microsoft Entra ID login via MSAL. Extensible social login provider architecture (Microsoft, Google, GitLab, Slack, Discord, DingTalk, Lark, WeCom, email/password).
- **Dashboard Layout** — Responsive admin dashboard with collapsible sidebar and role-based menu rendering.
- **User Management** — Data table with search, pagination, add/edit dialogues, role assignment, and phone number validation.
- **Role & Menu Management** — Role CRUD with authority assignment. Tree-based menu configuration.
- **Department & Position** — Organisation hierarchy management interfaces.
- **Protected Routing** — Route guards checking authentication and authorisation before page load.
- **State Management** — Redux Toolkit with Redux Persist for auth token persistence.
- **HTTP Client** — Axios wrapper with automatic JWT token injection and 401 refresh handling.
## Architecture
| Layer | Technology |
| ------------ | ---------------------------------------------------------------------------------------------- |
| **Frontend** | React 19, TypeScript, Tailwind CSS 4, Ant Design 6, React Router 7, Redux Toolkit, Axios, MSAL |
| **Backend** | Spring Boot 3.5, Java 21, Spring Security, MyBatis, Spring Data JPA |
| **Database** | PostgreSQL (with Flyway migrations) |
| **Cache** | Redis (session/token storage) |
| **Storage** | AWS S3 (asset uploads) |
The frontend communicates with the backend via a RESTful JSON API. Authentication flow uses JWT access tokens (short-lived) with refresh tokens stored in Redis. Microsoft Entra ID integration is handled client-side via MSAL and validated server-side.
## Repositories
Helix is a monorepo — both halves live in the same repository.
- [server/](https://github.com/onixbyte-opensource/helix/tree/main/server) — Spring Boot backend
- [web/](https://github.com/onixbyte-opensource/helix/tree/main/web) — React frontend
## Getting Started
Helix is designed as a template project. To start a new project:
1. Fork or clone the [Helix repository](https://github.com/onixbyte-opensource/helix).
2. Configure your database, Redis, and S3 settings in the backend.
3. Configure your authentication providers and API base URL in the frontend.
4. Run the backend: `./gradlew bootRun`
5. Run the frontend: `pnpm install && pnpm dev`
## License
Helix is open-source software released under the MIT License.
+25
View File
@@ -0,0 +1,25 @@
---
title: Open Source
---
Open-source projects developed by OnixByte.
## Libraries & Toolkits
- **[OnixByte Toolbox](/opensource-projects/onixbyte-toolbox)** — A development kit for Java applications: AES, hashing, Base64, collection utilities, crypto key loaders, statistical calculators, identity generators, and generic tuples.
- **[regions4j](/opensource-projects/regions4j)** — Type-safe ISO 3166-1 regional metadata as a Java enum with O(1) lookups, E.164 dialling codes, and locale tags.
- **[Captcha](/opensource-projects/captcha)** — A modern Java CAPTCHA generation library with water ripple, fish-eye, and shadow distortion effects.
- **[Calendar Toolbox](/opensource-projects/calendar-toolbox)** — A Java library for creating `.ics` files conforming to the iCalendar specification (RFC 5545).
## Full-Stack Applications
- **[Helix](/opensource-projects/helix)** — An enterprise application template with Spring Boot backend and React frontend, featuring JWT auth, RBAC, user and organisation management, and Microsoft Entra ID integration.
- **[Delta Force Guide](/opensource-projects/delta-force-guide)** — A web app providing a searchable library of firearm modification codes for the game _Delta Force: Havvk Ops_, with a React SPA and Spring Boot REST API.
## Developer Tools
- **[Claude Code Skills Manager](/opensource-projects/claude-code-skill-manager)** — A CLI tool for discovering, installing, and managing Claude Code skills from Git-based marketplace repositories.
## Vite Plugins
- **[Port Checker](/opensource-projects/vite-plugins/port-checker)** — Warns when the Vite dev server listens on a browser-restricted port, preventing silent connection failures.
@@ -0,0 +1,209 @@
---
title: OnixByte Toolbox API
---
## Package Overview
All modules are published under the `com.onixbyte` group ID. Each module has its own base package:
| Module | Maven Artifact | Base Package |
|----------------------|------------------------|---------------------------------------|
| Common Toolbox | `common-toolbox` | `com.onixbyte.common` |
| Crypto Toolbox | `crypto-toolbox` | `com.onixbyte.crypto` |
| Math Toolbox | `math-toolbox` | `com.onixbyte.math` |
| Tuple | `tuple` | `com.onixbyte.tuple` |
| Identity Generator | `identity-generator` | `com.onixbyte.identitygenerator` |
---
## Common Toolbox
### Adapter
`ObjectMapAdapter` — Converts between objects and maps. Useful for serialisation or data transformation scenarios where key-value representations are preferred.
```java
import com.onixbyte.common.adapter.ObjectMapAdapter;
```
### Utility Classes
| Class | Description |
|--------------------|----------------------------------------------------------|
| `AesUtil` | AES symmetric encryption/decryption with key generation |
| `Base64Util` | Base64 encoding and decoding with multiple charset support|
| `BoolUtil` | Boolean parsing and conversion utilities |
| `BranchUtil` | Conditional branching helpers with functional-style chains|
| `CollectionUtil` | Collection manipulation — grouping, partitioning, merging |
| `HashUtil` | Hashing utilities supporting MD5, SHA-1, SHA-256, SHA-512 |
| `MapUtil` | Map builder, merge, and transformation helpers |
| `RangeUtil` | Numeric range operations with boundary handling |
**AesUtil Example:**
```java
var key = AesUtil.generateKey();
var encrypted = AesUtil.encrypt("hello world", key);
var decrypted = AesUtil.decrypt(encrypted, key);
```
**HashUtil Example:**
```java
var md5 = HashUtil.md5("hello world");
var sha256 = HashUtil.sha256("hello world");
var fileSha = HashUtil.sha256(new File("data.bin"));
```
**CollectionUtil Example:**
```java
var partitioned = CollectionUtil.partition(list, 100);
var grouped = CollectionUtil.groupBy(users, User::getDepartment);
```
---
## Crypto Toolbox
Provides a clean abstraction for loading cryptographic keys in PEM format. Supports both RSA and ECDSA algorithms.
### Key Loaders
| Class | Description |
|---------------------------|--------------------------------------------|
| `RSAPrivateKeyLoader` | Load RSA private keys from PEM strings |
| `RSAPublicKeyLoader` | Load RSA public keys from PEM strings |
| `ECPrivateKeyLoader` | Load ECDSA private keys from PEM strings |
| `ECPublicKeyLoader` | Load ECDSA public keys from PEM strings |
All key loaders implement either `PrivateKeyLoader` or `PublicKeyLoader` interfaces.
**RSA Example:**
```java
var privateKey = new RSAPrivateKeyLoader().load(pemString);
var publicKey = new RSAPublicKeyLoader().load(pemString);
```
**ECDSA Example:**
```java
var ecPrivateKey = new ECPrivateKeyLoader().load(pemString);
var ecPublicKey = new ECPublicKeyLoader().load(pemString);
```
### Utility
`CryptoUtil` — Provides convenient methods for digital signature creation and verification, as well as general-purpose cryptographic helpers.
### Exceptions
| Class | Description |
|------------------------|---------------------------------------------------|
| `KeyLoadingException` | Thrown when a PEM-formatted key fails to parse |
---
## Math Toolbox
Statistical computation utilities for working with numeric datasets.
### Core Classes
| Class | Description |
|-------------------------|----------------------------------------------------------|
| `Calculator` | Statistical calculator for mean, median, variance, standard deviation, sum, min, max |
| `PercentileCalculator` | Percentile computation with configurable interpolation strategies |
**Calculator Example:**
```java
var stats = new Calculator(Arrays.asList(1.0, 2.0, 3.0, 4.0, 5.0));
double mean = stats.getMean();
double median = stats.getMedian();
double stdDev = stats.getStandardDeviation();
```
**PercentileCalculator Example:**
```java
var calculator = new PercentileCalculator(data);
double p95 = calculator.calculate(95);
double p99 = calculator.calculate(99);
```
### Model
| Class | Description |
|-------------------|----------------------------------------------------------------|
| `QuartileBounds` | Holds Q1, median (Q2), Q3 values along with IQR and whisker bounds |
---
## Tuple
Lightweight generic tuple types for when you need to return multiple values without defining a dedicated class.
### Classes
| Class | Type Parameters | Mutability |
|--------------------|-----------------|------------|
| `Tuple<A, B>` | Two elements | Mutable |
| `ImmutableTuple<A, B>` | Two elements | Immutable |
| `Triple<A, B, C>` | Three elements | Mutable |
| `ImmutableTriple<A, B, C>` | Three elements | Immutable |
**Example:**
```java
var pair = Tuple.of("key", 42);
var triple = Triple.of("id", "name", 100);
var immutable = ImmutableTuple.of("constant", true);
// Accessors
String first = pair.getFirst();
Integer second = pair.getSecond();
// Triple accessors
String a = triple.getFirst();
String b = triple.getSecond();
Integer c = triple.getThird();
```
---
## Identity Generator
Generates unique identifiers suitable for use as database primary keys or distributed IDs.
### Interface
`IdentityGenerator<T>` — Generates identities of type `T`.
### Implementations
| Class | Description |
|------------------------------|-----------------------------------------------------------------|
| `SequentialUuidGenerator` | Generates time-ordered, sequential UUIDs (optimised for DB indexes) |
| `SnowflakeIdentityGenerator` | Snowflake-style distributed unique ID generation |
**Sequential UUID:**
```java
var generator = new SequentialUuidGenerator();
UUID id = generator.nextId(); // time-ordered UUID, B-tree friendly
```
**Snowflake:**
```java
var generator = new SnowflakeIdentityGenerator(workerId, datacenterId);
long id = generator.nextId(); // 64-bit snowflake ID
```
### Exceptions
| Class | Description |
|-------------------|----------------------------------------------------------------|
| `TimingException` | Thrown when the system clock moves backwards, compromising ID uniqueness |
@@ -0,0 +1,54 @@
---
title: OnixByte Toolbox
---
import { Tabs, Tab } from "@rspress/core/theme"
## Introduction
OnixByte Toolbox is a Development Kit for Java applications that provides a set of convenient, reusable tools for writing code efficiently. It is designed and maintained by OnixByte as a monorepo containing multiple purpose-built libraries, each addressing a specific development need — from common utilities and cryptography to mathematical computation and identity generation.
The toolkit is available on Maven Central under the `com.onixbyte` group ID. Each module is independently versioned and can be included in any Java 17+ project.
## Modules
| Module | Artifact ID | Description |
|--------------------|----------------------|---------------------------------------------------------------------------|
| Common Toolbox | `common-toolbox` | Everyday utilities — AES, hashing, Base64, collections, branching, ranges |
| Crypto Toolbox | `crypto-toolbox` | Public/private key loading for RSA and ECDSA algorithms |
| Math Toolbox | `math-toolbox` | Statistical calculation, percentile analysis, quartile computation |
| Tuple | `tuple` | Generic 2-tuple and 3-tuple with immutable variants |
| Identity Generator | `identity-generator` | Snowflake-style and sequential UUID identity generation |
| Version Catalogue | `version-catalogue` | Centralised Gradle version catalogue for OnixByte projects |
## Installation
Add the desired module as a dependency in your build config:
<Tabs>
<Tab label="Gradle with Kotlin DSL">
```kotlin title="build.gradle.kts"
dependencies {
implementation("com.onixbyte:$artefactId:$version")
}
```
</Tab>
<Tab label="Maven">
```xml title="pom.xml"
<dependency>
<groupId>com.onixbyte</groupId>
<artifactId>${artefactId}</artifactId>
<version>${version}</version>
</dependency>
```
</Tab>
</Tabs>
## Requirements
- Java 17 or later
## License
OnixByte Toolbox is open-source software released under the MIT Licence.
@@ -0,0 +1,98 @@
---
title: Regions for Java
---
## Introduction
**regions4j** is a lightweight, type-safe Java library that provides comprehensive metadata for world regions based on the ISO 3166-1 standard. It is designed to simplify internationalisation (i18n), telecommunication routing, and regional data management in Java-based enterprise applications.
The library models every ISO 3166-1 country and territory as an enum constant, giving you compile-time safety and IDE autocompletion when referencing regions. With built-in O(1) lookups, zero external dependencies, and Java 8 compatibility, it is suitable for projects of any size — from microservices to monolithic enterprise systems.
## Features
- **ISO 3166-1 Compliant** — Full support for Alpha-2 (`abbreviation`) and Alpha-3 (`code`) formats across all assigned countries and territories.
- **Telecommunication Metadata** — Includes E.164 international dialling prefixes for every region.
- **Locality Support** — Default locale tags (`zh_HK`, `en_US`, `en_GB`, etc.) for each region to assist with i18n workflows.
- **High Performance** — Thread-safe, immutable internal hash maps provide constant-time lookups by abbreviation or code.
- **Zero Dependencies** — A pure Java library with no external overhead.
- **Calendar Versioning** — Versions follow a `YYYY.MM` scheme (e.g. `2025.12`) to transparently indicate the freshness of the underlying ISO data, rather than semantic versioning.
## Core Schema
Each region exposes four attributes:
| Attribute | Type | Description | Example |
|----------------|--------|---------------------------------|------------------------------------|
| `abbreviation` | String | ISO 3166-1 alpha-2 abbreviation | `HK`, `US`, `GB`, `RU` |
| `code` | String | ISO 3166-1 alpha-3 code | `HKG`, `USA`, `GBR`, `RUS` |
| `callingCode` | String | E.164 international dialling prefix | `852`, `1`, `44`, `7` |
| `locale` | String | Default language and region tag | `zh_HK`, `en_US`, `en_GB`, `ru_RU` |
## Installation
**Maven:**
```xml
<dependency>
<groupId>com.onixbyte</groupId>
<artifactId>regions4j</artifactId>
<version>2025.12</version>
</dependency>
```
**Gradle (Kotlin DSL):**
```kotlin
implementation("com.onixbyte:regions4j:2025.12")
```
> **Versioning note:** This library uses Calendar Versioning (`YYYY.MM`) rather than Semantic Versioning. A version string like `2025.12` tells you immediately that the regional data reflects the ISO 3166-1 state as of December 2025.
## Usage
### Direct Access
Reference any region directly via its enum constant:
```java
Region uk = Region.UNITED_KINGDOM;
uk.getAbbreviation(); // "GB"
uk.getCode(); // "GBR"
uk.getDialCode(); // "44"
uk.getLocale(); // "en_GB"
```
### Efficient Lookups
Look up regions from string inputs — ideal for processing web requests, API payloads, or database records:
```java
// By Alpha-2 abbreviation (case-sensitive)
Region region = Region.fromAbbreviation("HK");
// By Alpha-3 code (case-insensitive)
Region region = Region.fromCode("HKG");
```
### Java Locale Integration
Convert a region's locale string to a `java.util.Locale` for use with standard Java i18n APIs:
```java
Region region = Region.CHINA;
Locale javaLocale = Locale.forLanguageTag(region.getLocale().replace("_", "-"));
javaLocale.getDisplayCountry(Locale.UK); // "China"
```
## Performance
On first access, the library initialises all regions into immutable `HashMap` structures. Subsequent lookups via `fromAbbreviation()` and `fromCode()` are thread-safe and run in constant time — suitable for high-throughput request paths.
## Requirements
- Java 8 or later
## License
regions4j is open-source software released under the MIT License.
@@ -0,0 +1,11 @@
---
title: Vite Plugins
---
## Overview
A collection of Vite plugins developed and maintained by OnixByte. Each plugin is designed to solve a specific problem in the Vite development workflow — lightweight, zero-dependency, and plug-and-play.
## Available Plugins
- **[Port Checker](/opensource-projects/vite-plugins/port-checker)** — Warns when the dev server listens on a browser-restricted port (per the Fetch specification), helping you avoid silent connection failures.
@@ -0,0 +1,68 @@
---
title: Port Checker
---
import { Tabs, Tab } from "@rspress/core/theme"
## Introduction
**vite-plugin-port-checker** is a lightweight Vite plugin that warns you when the dev server is listening on a port blocked by common browsers. Browsers such as Chrome and Firefox maintain a [list of restricted ports](https://fetch.spec.whatwg.org/#port-blocking) — typically those associated with well-known protocols like SMTP, SSH, and DNS — and refuse to connect to them. Accidentally running your dev server on one of these ports leads to a confusing "connection refused" or "blocked" error with no clear explanation.
This plugin detects the situation at startup and prints a clear, colour-coded warning to the console, advising you to change the `server.port` setting in your Vite configuration.
## Features
- **Automatic Detection** — Checks the dev server port against the complete Fetch spec port-blocking list (68 restricted ports).
- **Clear Warnings** — Yellow-highlighted console output with actionable guidance.
- **Zero Configuration** — Works out of the box with no options to set.
- **Lightweight** — Single-file plugin with no dependencies beyond Vite itself.
## Installation
<Tabs>
<Tab label="npm">
```bash
npm install vite-plugin-port-checker -D
```
</Tab>
<Tab label="pnpm">
```bash
pnpm add vite-plugin-port-checker -D
```
</Tab>
</Tabs>
## Usage
Add the plugin to your `vite.config.ts`:
```ts
// vite.config.ts
import { defineConfig } from "vite"
import checkRestrictedPort from "vite-plugin-port-checker"
export default defineConfig({
plugins: [checkRestrictedPort()],
})
```
When the dev server starts on a restricted port (e.g. port 25, 22, or 53), you will see:
```
[Warning] The current listening port 25 is categorised as a restricted port
by most browsers. This may prevent you from accessing the application.
Please consider changing the port in your 'vite.config.ts' or 'vite.config.js'
via 'server.port'.
```
## How It Works
The plugin hooks into Vite's `configureServer` lifecycle. Once the HTTP server emits the `listening` event, the plugin inspects the bound port and checks it against the hardcoded set of 68 restricted ports defined in the [Fetch specification](https://fetch.spec.whatwg.org/#port-blocking). If there is a match, a yellow `console.warn` message alerts the developer.
## Requirements
- Vite 3.0.0 or later
## License
vite-plugin-port-checker is open-source software released under the MIT License.