Lightingale Documentation

Welcome to the documentation hub of the Lightingale Community. See the sidebar for the list of documentations available.

To see a list of active projects not included here, feel free to visit the project website for the whole list, or GitHub pages host for projects hosted on GitHub.

Site powered by mdBook.

Clearnet CDNs are generously provided by Cloudflare, GCoreLabs, CloudFront, CacheFly and Fastly free of charge.

Services

For shorter descriptions, see Lightingale Services List.

  • Lavender: Reddit-like Fediverse instance for the MLP fandom and LTGC.
  • Liquestria: Invite-only semi-anarchy Minecraft survival multiplayer on mixnet.
  • Matrix services: Managed Matrix bridges and more.

Projects

POSIX Shell

  • Gel: ⛏ Rolling server bases, batteries included.
  • Hyacinth: 💨 Build web projects with speed.
  • Iceflakes: ❄️ Offline Linux installer images for everyone.
  • Nightglow: 🌙 Yet another Cloudflare WARP client wrapper.
  • shx: 📜 Bash/PDKSH shell action executor.
  • Stratus: ☕️ JavaScript runtime containers (Deno, Bun, Node.js).

Data sheets

  • midi-db: 🎹 Data concerning MIDI standards.
  • Raven: 💨 Lightning-fast intuitive typing.
  • SynPix: 👾 The open pixel font for embedded LCDs.

Rust

  • Ensemble: 🎶 A synth framework in Rust.

Go

  • Floaty: ☁️ Prevent Caddy loopbacks... Without traceability.
  • Pulsewave Desktop: 🔊 Universal modularized cross-device audio connections (Linux, Windows, macOS).
  • Trampoline: 🥁 Chat sockets to Matrix bridge.
  • Usher: 🚸 Rolling sticky hash load balancing on Caddy.

Java

Kotlin

  • Cotton: 💬 PSK-authenticated Minecraft chat socket.
  • Pulsewave Android: 🔊 Universal modularized cross-device audio connections (Android).

JavaScript

  • Berry: 🍇 Simple port exposure tunnel for stream entropy manipulation.
  • Bread: 📦 Unified framework to stream binary in blocks.
  • Crystal Quartz: 🎨 A colour palette generation system.
  • Ditzy: 📬 Reconstruct stateful sockets over stateless messages.
  • Eclipsed: 🔊 The Royal Canterlot Voice for SSE/EventSource.
  • Flitter: 🗂 A file viewer for the web, with minimal requirements.
  • Heartstrings: 📑 Create and modify lyrics and subtitles as quick as possible.
  • Inkwell: 📒 The grand central terminal / Le grand terminal central.
  • Leaflet: ⚠️ Stock Caddy error pages, free for anyone to use if kept credits.
  • Lightfelt: 🕸 A collection of JS snippets for the Web and Deno.
  • Mint: 🌱 Easy-to-configure load balancing serverless functions.
  • Minuette: ⏳ Intercept, inspect, orchestrate.
  • Octavia: 🎻 Event-driven multi-standard MIDI state-tracking library.
  • Painted Palette: 🎨 Painting palettes, one pixel at a time.
  • Parchment: 📃 Mark-down based client-side page generator.
  • Rochelle: 🔪 Stream chunk splitting.
  • Scope: 🔭 Easy-to-setup WireGuard meshing.
  • Silk: 🕸 Bringing the fandom together.
  • Snowy: ❄️ The BroadcastChannel polyfill for Firefox 29+ and Chrome 5+.
  • Track me, senpai!: 🍑 Just giving thanks to your visitor sharing their everything with you.
  • Twinkle Sprinkle: 📜 Task wait signals and simple WAL.
  • WingBlade: ☁️ One codebase, multiple runtimes.

Privacy policy

As of 6th Oct 2023, these terms are not yet in effect.

By using services provided by the Lightingale Community, you agree to the following terms.

Default

Unless stated explicitly otherwise, the following policy will be applied to any web-based service run by the Lightingale Community.

TL;DR, we have access to all of the data the client implementation chooses to share with us, but unless an error is caused or you explicitly want us to, none of the data would be stored.

Accessible

Below is the list of data accessible by us if provided, on the server-side without user interaction.

  • When accessing via clearnet, the IP address of your exit.
  • When accessing via clearnet, IP packet fingerprints. (e.g. TCP fingerprint, UDP fingerprint)
  • TLS connection fingerprint, when connected via TLS.
  • Standardized client-identifying headers, if provided. Visit MDN for more information. Below is a list of possible headers, and may not include all headers.
    • Accept: Which types of content is accepted by the client.
    • Accept-Encoding: Encoding schemes accepted by the client, usually compression algorithms.
    • Accept-Language: Languages expected by the client.
    • Authorization: Tokens proving client's identification.
    • Origin: The URL of request's origin.
    • Referer: The initiator URL of each request.
    • Sec-Fetch-Dest: The initiator type of each request.
    • Sec-Fetch-Mode: Mode applied on requests.
    • Sec-Fetch-Site: Relationship between requested resource and source.
    • User-Agent: Implementation identification string provided by the client.
    • X-Forwarded-For, X-Real-IP: If behind a reverse proxy, the connecting IP address observed by the reverse proxy. These headers are almost always stripped, spoofed or generalized on reverse proxies we have control of however.
  • Client hints, sent by Chromium-based browsers (e.g. Google Chrome). Below is a list of headers sent unconditionally by Chromium-based browsers. To prevent us from receiving these headers, please switch to a browser that isn't based on Chromium.
    • Sec-CH-UA: Array of implementation identification strings provided by the client.
    • Sec-CH-UA-Mobile: If the client runs on mobile platforms (e.g. Android, iOS).
    • Sec-CH-UA-Platform: The platform running the client, usually OS families.
  • All other headers clients choose to provide.
  • When the service involves server-side dynamically-generated content, basic cookies allowing said service to function properly.

We also have access to data you explicitly choose to share with us. They may be in cleartext or in their encrypted form.

Use

General

  • Data explicitly stored by users will likely persist until takedowns.
  • During suspected infiltrations, we will use any information accessible to identify and exterminate unauthorized access. Data stored during this period will be removed as soon as related investigations are finished.
  • We do not share any information with any third-parties.
  • Data requests from individuals and law enforcement agencies will be assessed before any action is taken. See the data request section for details.

Low-importance

Unless overriden, these uses do not store data.

  • To deny access from clients we deem as unfit of service (WAF), we will use Origin, Referer, Sec-CH-UA, Sec-Fetch-Site, User-Agent, observed client IP address (if on clearnet/behind reverse proxies), IP packet fingerprints (if on clearnet) and TLS fingerprint.
  • To conserve bandwidth whenever we can, we will use Accept-Encoding.
  • To serve content to client's expectation, we will use Accept.
  • To distinguish between sessions if essential to the service client accesses, Authorization and/or basic cookies will be used.
  • To serve localized content in client's desired languages, we may use Accept-Language.

Medium-importance

Data stored from these uses will be kept for at most 7 days.

  • Requests will be logged without observed IP addresses only upon causing non-critical software errors.

High-importance

Data stored from these uses will be kept for at most 365 days.

  • Requests will be logged with observed IP addresses only upon causing critical software errors, or attempting to utilize known exploits.

Data access/removal request

  • Approved data requests will be fulfilled within 30 days since approval, in the form that's available to us. Encrypted data will be provided as-is, along with their respective decryption keys only if available.
  • Individuals can file requests for their data, and will be approved upon proving ownership.
    • In most cases, individuals have power to remove data on their own.
  • Law enforcement agencies can file requests for data. All data requests filed from law enforcement agencies will be made public.
    • Requests sent from law enforcement agencies will only be approved if all listed criteria are satisfied.
      • Belongs to a political body deemed as "full democracy" or "flawed democracy" by The Economist Democracy Index.
      • Provides sufficient information for proving their identity.
      • Belongs to the political body where related services are hosted, or can provide proof that affected users violated our acceptable usage policy.
    • Affected resources of fulfilled removal requests from law enforcement agencies will be marked as 451 Resource Aflame, along with the name of requested agency.
  • If the service's ability to continue operation becomes next-to-impossible due to a failed compliance from a rejected data request, we will wipe all data stored on our behalf and cease operation on said service. The same goes for the Lightingale Community itself.

Infrastructure providers

We extensively rely on Cloudflare for our infrastructure on the clearnet. If you do not want to go through Cloudflare, feel free to access our services through alternative means. Otherwise, a copy of privacy policy from Cloudflare could be obtained.

To improve availability and/or decrease cost on some of our services, we may also use other infrastructure providers. Check their respective privacy policies for details. Below is a list of providers we rely on.

  • AWS CloudFront, for CDN.
    • Anonymized/generalized data generated by AWS CloudFront are stored for 30 days by the provider.
  • AWS Lambda, for serverless computing.
    • Anonymized/generalized data generated by AWS Lambda are stored for 30 days by the provider.
  • CacheFly, for CDN.
    • Data generated by CacheFly are never stored.
  • Cloudflare, for DNS, CDN, WAF and edge serverless computing.
    • Identifying data generated by Cloudflare are stored for 24 hours by the provider.
    • Anonymized/generalized data generated by Cloudflare are stored for 30 days by the provider.
  • Deno Deploy, for edge serverless computing.
    • Anonymized/generalized data generated by Deno Deploy are stored for 30 days by the provider.
  • Fastly, for CDN and edge serverless computing.
    • Data generated by Fastly are never stored.
  • GCoreLabs, for CDN.
    • Anonymized/generalized data generated by GCoreLabs are stored for 30 days by the provider.

Access denial

VPN

If you're accessing any Lightingale service from a VPN, chances are you're already blocked by us, but will get unblocked if with mixnets like Tor, or encrypted proxies. This is intentional.

We strongly support privacy and anonimity, while also highly detest the idea of fattening any commercial VPN vendor. VPNs do not offer privacy or security on the Internet in any way, let alone either anonimity or anti-censorship, and in no way any of them contribute to the effort of developing either anti-censorship or concealing technology to truly liberate the masses. As such, we've long since decided to take direct action, actively identifying and fingerprinting VPNs, while advising people to switch to real solutions instead.

Client

We identify some client programs as high-risk, and block requests from those programs if identified.

FAQ

I'm using a VPN, what should I do?

To put it simply, please stop using a VPN to access us.

If you're familiar with accessing services hosted on mixnets, you can access our services via alternative means. Or if you don't want to go through the hassle, please disconnect from your VPN, and if you have access to either exit/outproxy-enabled mixnet (e.g. Tor, I2P (I2Pd is recommended if you are comfortable with command line), Lokinet) or encrypted proxies, use them instead.

What if I'm blocked wrongly?

Within 18 hours, please contact us and provide your Cloudflare Ray ID in your unblocking appeal. After we've verified that you did indeed not connect from a VPN, you'll be unblocked as soon as possible. However, if you used a client program we deem as high-risk, we will reject your appeal immediately.

Could you stop blocking VPNs?

No.

Acceptable Usage Policy

These terms do not yet have legal liabilities, however they are enforced.

Underlined terms should have definitions available in the Definitions section.

Definitions

  • Child pornography: Depictions of underage humans or underage characters resembling humans.
  • Underage: Below 18 years old.

Disallowed use

AUP does not cover cases where reasons of policy enforcements are explained.

  • Reselling any of our public services, which is free-of-charge for all.
  • Breaching the awareness scope defined by projects/services.
  • Scanning us or to scan others (e.g. port scanning).
  • Gaining unauthorized resource access.
  • Degrading the performance of our servers (e.g. flooding).
  • Violating others privacy (e.g. doxxing).
  • Impersonating existing identities without stating satire status.
  • Exploiting stolen identities.
  • Distributing unsolicited data (e.g. spam).
  • Scamming.
  • Hate speech (e.g. racism, xenophobia).
  • Promotion of self-harm (e.g. suicide).
  • Harming others physically or psychologicaly (e.g. torture threats, death threats, harassement).
  • Engaging in distribution of illegal substances, human organs, guns and etc.
  • Promoting, encouraging and/or beautifying any of the following topics.
    • Crimes against humanity (e.g. massacre).
    • Terrorism, its practices and exercising organizations.
  • Distributing content matching any of the following criteria, without explicit warning to the target audience.
    • Malware.
    • Phishing content.
    • Pornography.
  • Distributing and storing content matching any of the following criteria.
    • Child pornography.
    • Pornography without consent of involved parties.
  • Defaming us without any validated proof.

Terms of Service

This agreement will become legally binding once Lightingale Community becomes a legally-registered non-profit organization.

As of 6th Oct 2023, these terms are not yet in effect.

In this agreement...

  • The term "you" or "your" refer to "the user".
  • The term "we", "us" or "our" refer to Lightingale Community itself and its members.
  • The term "service" or "services" refer to publicly-available listed services hosted on behalf of Lightingale Community. The list is available here.

By accessing content or using the services provided by the Lightingale Community, you agree to the following terms. Specific services will apply amendments to fit their specific needs.

Any material changes to these terms will be publicly notified via our Mastodon and our Telegram channel at least 7 days prior. If you wish to exercise your right to reject such changes, you can file complaints to us, or stop using the service altogether.

Disclaimer

  • We reserve the right to modify the service, including but not limited to changing certain features and updating the related software.

  • We reserve the right to terminate your access to some or all of our services.

  • We may deny access to certain services based on the geographic location of your immediate connection.

  • We will attempt to prevent disruptions, defects and losses of data in our offered services, but despite our best efforts, we do not and can not guarantee availability of all times, and we are not responsible for materials served by us. Our service comes with absolutely no warranty, to the extent permitted by applicable law. You are solely responsible for your use of service.

The service

This section is defined in different services we offer to the public.

Software

Lightingale Community is powered fully by and produces FOSS, fit under the definition set by the Free Software Foundation. Further acknowledgements may be made in README files when we use software projects that require them.

Our content

Except for software, unless stated otherwise explicitly, content belongs to us is licensed under CC BY-NC-SA 4.0 License. Our members hold the rights of content they produced.

Your content

This section applies to services offering UGC.

You hold the rights to your own content, but you give us a license when submitting your content to us. Upon submission, you permit us to do the following to your submitted content. These terms are world-wide, non-exclusive, royalty-free, transferrable and perpetual.

  • To store and display your content, you permit us to use, copy, store, distribute your content in ways consistent with your use of the services.
  • To adapt your content for use of different platforms by different users with various backgrounds, you permit us to monitor, modify, translate and reformat your content.
  • For public availability, you permit us to publish, publicly perform, or publicly display your content, if you've chosen to make it visible to others.
  • To allow our services to work as intended, you permit us to sublicense your content.

We reserve the right to block, remove or wipe your content if in breach with these terms or other terms in effect.

Acceptable usage

As a user of services offered by us, you agree to adhere to our acceptable usage policy. Violations of AUP will result in a termination, and may result in your data made available to law enforcement agencies.

We encourage you to report abuses of our services with proof. We accept reports made via email at abuse (at) ltgc (dot) cc.

Donation

This section is subject to changes as our legal status changes.

We are not responsible for fulfilling any additional requirement attached to the donations made to us.

Applicable law

This section is subject to change as our legal status changes.

This section is subject to change as our legal status changes.

Legal contacts may be filed via email to legal (at) ltgc (dot) cc. We do not have a physical location available.

UGC Availability

To prevent Lightingale Community from getting blocked as a whole in certain countries, we've been forced to restrict or deny direct access from those countries. A restricted service coverage would've been marginally better than nothing at all.

We offer two levels of UGC services: high-liberty and restricted. Levels are separated by the measures avalable to the users, and users' ability to freely express whatever they desire. Some countries may have been denied direct access from high-liberty UGC services, but not restricted ones.

If you've been redirected to this page, we have no choice but to offer our deepest apology.

Technologies

Preferred technologies

Languages and runtimes

Networking

Operating systems

Virtualization and containerization

Miscellaneous

Used technologies

Technologies listed here have some of our projects using them. None of the technologies listed below are a preference, although project can freely choose to use them.

Languages and runtimes

Virtualization and containerization

Miscellaneous

Avoided technologies

Technologies listed here will have their usage be discouraged and avoided. However, projects can still develop for them only if necessary. Software already developed with these technologies can also be deployed.

Languages and runtimes

Operating systems

Miscellaneous

Banned technologies

Usage of technologies listed here are entirely banned within LTGC. Bans do not extend to members themselves.

Frameworks

Miscellaneous

Content encoding

None of the encodings listed are involved with patent concerns.

Usage Encoding Extension
Rasterized image JPEG XL .jxl
WebP .webp
Vector image SVG .svg
Lossy audio Opus .opus
Vorbis .ogg
AAC-LC .m4a .aac
Lossless audio WavPack .wv
FLAC .flac
Web compression Brotli .br
gzip .gz
Bundle compression xz .xz .txz
bzip2 .bz2 .tbz2
lzip .lz .tlz
Font WOFF2 .woff2

Read below for further details.

Rasterized image encoding

Lossy

As WebP is properly supported in every browser built for systems newer than Windows XP, and it offers better quality-to-size ratio than all JPEG encoders, it is considered the best fallback format. However, as JPEG XL exists as an all-around better universal image format, lossy images should also be encoded with JPEG XL whenever possible.

Compared to all other image formats, JPEG XL offers jawdropping image fidelity, unmatched quality-to-size ratio, proper progressive loading and better responsiveness. The cherry on top of JPEG XL would be its ability to losslessly transcode from existing JPEG files, offering about 20% size reduction with cheap JPEG lossless bitstream reconstruction, which paves its way to be a backwards-compatible drop-in replacement for image storage and distribution.

MozJPEG-fronted JPEG XL encoding hasn't been tested yet.

Codec Use Params
JPEG XL Delivery cjxl -d 2.2 -e 4 -p
Archival cjxl -d 1.1 -e 4 -p
WebP Delivery cwebp -m 5 -psnr 56
Archival cwebp -m 5 -q 99

The full feature set comparison chart is available on Cloudinary.

Battle of the image codecs!

Lossless

WebP Lossless should always be offered when lossless image codecs are required. JPEG XL Lossless should only be offered alongside when it proves to be smaller than WebP in a case-by-case scenario.

Audio encoding

Lossy

When high sampling rates are required, choose Vorbis. When support for the Apple ecosystem is required, choose AAC-LC. Otherwise use Opus under all possible scenarios, but beware that Opus only supports sampling at 48kHz.

Below are the suggested bitrates under different scenarios, when encoding stereo audio content under either 44.1kHz or 48kHz. Audio content should be encoded with constrained variable bitrate (CVBR).

The AAC-LC encoder in question is libfdk_aac, being the best FOSS AAC-LC encoder out there. The only AAC-LC encoder better than libfdk_aac is Apple's Audio Toolbox, which is proprietary and not in consideration.

CodecBasicStreamBalancedGenericQuality
Opus96kbps144kbps160kbps192kbps256kbps
Vorbis128kbps160kbps192kbps224kbps320kbps
AAC-LC128kbps160kbps192kbps224kbps320kbps

Keep in mind that the scenario under "basic" indicates that, all audio content encoded with provided parameters should be virtually undistinguishable from LAME-encoded MP3 files at 192kbps.

Lossless

Streaming lossless audio is generally considered a bad idea.

When web support isn't planned, or the target platforms aren't severely underpowered, WavPack is the recommended codec for storing lossless audio. Recommended encoding parameters for the official CLI util: wavpack -hhvx -x 3

Compression

Web

Brotli should be preferred over gzip at all times. Static low-entropy content (e.g. plain text files) should always be pre-compressed, with or without the original uncompressed file available.

For static precompression, the original file can be omitted when the space is constrained, serving only precompressed blobs. When compatibility with other infrastructure isn't in consideration, precompressed gzip files can also be omitted, although it's not recommended in most cases.

Algorithm Use Params
Brotli Real-time brotli -4
Precompression brotli -q 11
gzip Real-time gzip -4
Precompression zopfli --i25

Bundle

bzip2 should be the default bundle compression algorithm, unless either lzip or xz is proven to be better in a case-by-case scenario. Quality should always set to 9, unless a lower quality value is proven to yield a better result for smaller files.

Due to platform differences, xz should be avoided for automation scripts that may install compression algorithms on the fly.

Font

As practically all modern browsers support the WOFF2 font format, all required TrueType and OpenType fonts must be served as WOFF2 files instead. If for unspecified reasons that original files must be served, always consider precompression and avoid storing uncompressed files.

Lavender

Lavender is a friendly discussion lounge for both the My Little Pony fandom and LTGC, powered by the magic of Lemmy. No matter what you are, be a pony, dragon, hippogriff or draconnequus, you're welcome here!

Lavender adheres to the general Terms of Service and Acceptable Usage Policy.

The incubator thread can be viewed here.

Access

Addresses

The service can be accessed from the addresses listed below.

Panels

Read Lavender panels.

Account registration

Alpha phase

Lavender is still in the alpha phase. During the alpha phase...

  • Only people already having a presence on Fediverse can apply for account registration. You must fulfill any criteria listed below.
    • Have an account on one of the listed public instances for more than 14 days, with at least 7 posts in total.
    • Have an account on any public Fediverse instances for more than 14 days, with at least 7 posts in total, and the identity relates to the My Little Pony fandom.
    • Be a member of the Lightingale Community.

Moderation

Alpha phase

Lavender is still in the alpha phase. During the alpha phase...

  • Only accounts on the instance itself can apply to become a moderator.
  • Only with two or more

Lavender Panels

Lavender currently organizes the following panels.

Best of Fedi Pones

Artists new to the Fediverse often complain about not reaching enough audiences. So what's the solution? Well, with a weekly panel promoting pony artworks published on the Fediverse, of course!

Organized by a group of Fediverse enthusiasts from the My Little Pony fandom, Best of Fedi Pones seeks to bring what the Fediverse has to offer to everyone enjoying the creativity from the pony fandom. Better together!

Source code: Codeberg

Artwork submission

Submitting artworks will get them included in the issues of Best of Fedi Pones if not denied. All submitted artworks, unless violating AUP, will be also referenced by the MLP English Lavender community.

Submitting artworks

Best of Fedi Pones has been directly integrated into the Fediverse since issue 10. Submission only requires the inclusion of #weeklypony tag while also mentioning @[email protected]. Works both when posting yourself and replying to others.

Inclusion denial

Submissions will be denied if they match at least one of criteria listed below.

  • Is not SFW.
  • Is generated by neural networks. Inspired by or assisted with NN doesn't count.
  • Not posted by the artist themself.
  • Violates LTGC AUP.
  • Was posted for longer than 14 days to the deadline of the target issue.

Voting and issuing

Voting of each submission is done in a room accessible to all panel organizers. While the room is bridged to Discord and Telegram, only votes from Matrix and Discord are counted due to technical limitations.

Each eligible voter can part one ⭐️(:star:) emoji to give a submission an upvote. Submissions with high vote count will be ordered first, and submissions sharing the same vote count have their exact order determined by the hash of the origin URL. No downvotes are available.

Voting of each issue generally begins at 12:00 UTC +0 on every Saturday, and ends at 18:00 UTC +0 on the next day. The dataset should be available shortly after the voting ends, and any organizer can release the issue with the dataset.

To prevent accusations of theft, except for the cover art, all submission images must be hotlinked from source. Cover art is generally selected among the submission with the top 60% vote count, entirely by the organizer posting the issue with their own preferences. However, it's advised to avoid featuring the same artist within the span of 9 issues, and artists new to the Fediverse are advised to be preferred.

Matrix services

Lightingale Community has been hosting Matrix services for ease of communication, ever since the community's early days in 2021.

Homeserver

We run a Synapse homeserver for hosting all of our bridges and for internal communication. Only members of the Lightingale Community can apply for accounts on the homeserver.

Bridges

As long as adhereing to the Acceptable Usage Policy, members on our homeserver can freely use any of the bridges we host.

Platforms

Managed bridges to the following platforms are offered by us.

Group chat

The following bridges support both group chats and direct messages.

Direct message

The following bridges only support direct messages.

Known issues

Global

  • Due to some unknown bug in Caddy, requests with bodies larger than 1000 KiB will be cut off by Caddy without emitting errors. This will cause some media messages fail to upload, and in turn, get bridged.
    • This is an issue plaguing all of the web infrastructure within LTGC for quite some while now.
  • Animated stickers on certain platforms may only get their first frame be bridged, due to varying media codec support on different platforms.
  • Double-bridged replies may not work on certain platforms.
  • The bridge may become unresponsive when overloaded. You can help us relieve this problem via donations!

Telegram

  • Reactions aren't bridged from Telegram.
  • The Telegram bridge suffers from downtimes caused by Python, the underlying runtime. It has to be manually rebooted.
  • The Telegram bridge will randomly become unresponsive for no other reason than the underlying Python runtime.
  • Bot messages from Telegram cannot be bridged to other platforms, per Telegram's restriction.
  • Senders from other platforms cannot be transparently bridged to Telegram, requiring embedding their display names as message content.

Discord

  • Due to Discord validating time-sensitive HMAC codes on attachment URLs, media from Discord cannot be bridged currently.
    • This was fixed on 27th March 2024, where a combination of active and passive media proxying was deployed.
  • Some of the animated stickers were vector images encoded in custom-defined JSON files. As a result, none of the services other than Discord recognizes them.

Bridging service

FLOSS projects

If applied and approved, we will offer free bridging services to the approved FLOSS projects.

MLP fandom communities

We offer free bridging services to the approved communities within the MLP fandom after approval.

Not-for-profit entities

We offer free bridging services to not-for-profit entities after approval.

Matrix media repo services

Active Discord media proxy

As Discord began requiring expiring HMAC validations on media attachments, the Discord bridge now switches to an active proxying approach, before reuploading/re-serving re-encoded optimized media attachments becomes viable. Files delivered via this new approach will be served at dma.ltgc.cc.

Passive Discord media proxy

Due to MSC3860 being unsupported on homeservers without conformation of the Matrix 1.7 specification, homeservers will not recognize discord-media.mau.dev, the public redirecting Discord media repo. To circumvent this, we offer a custom cached Discord media proxy at dmr.ltgc.cc instead for use of bridges, however it will likely be shut down to public access if we notice it getting abused.

After Discord implemented expirations on media attachment links with HMAC validation, the media proxy now only serves non-attachment files, like avatars, stickers and custom emojis. Since passive media proxy is less costly to run than active media proxies, it's used whenever possible.

Ditzy

Ditzy is a transport-agnostic universal multi-message encoding scheme, allowing stateful bidirectional communications regardless of the statefulness of the underlying transport. With the state of the reconstructed tunnel fully decoupled from the underlying transport, possibilities are endless. How Ditzy performs is entirely dependent on implementation.

This project is inspired by Tor HTTP Meek, MIDI 1.0 and QUIC.

💌 Feel your messages delivered safely by your trustworthy Ponyvillan mailmare!

The first draft was written on 18th Nov 2021, with the next iteration on 5th Feb 2023. The current draft is written on 29th June 2023.

Advantages

  • State of tunneled connections are decoupled from their underlying transports
  • Seamless connection migration on connection losses and IP changes
  • Total control over frame transmission

Use cases

  • Bidirectional communication through incapable infrastructure (e.g. CDNs, request reflectors)
  • Stablizing communication over unstable networks
  • Replacing QUIC where UDP communication is not feasible
  • Connection multiplexing
  • Connection splitting

Specifications

Reference implementation API docs

JavaScript

DitzyDriver

The underlying transport interface to be used by DitzyStream. Connection management and congestion control happens here.

This interface needs to implement the following public methods to let DitzyStream function properly.

DitzyDriver {
	send(): WritableStream, // Where data gets sent out
	onmessage: ReadableStream, // Where data gets received
}

DitzyStream

The master stream, where underlying sockets gets multiplexed and de-multiplexed. Individual sockets can be established with DitzySocket or DitzyPipe.

DitzyStream {
	driver: DitzyDriver, // The underlying driver
	pipe(): DitzyPipe, // Creates a new connection
	sock(): DitzySocket, // Creates a new connection
}

DitzyPipe

The raw interface sending data to and receiving data from as streams.

DitzyPipe {
	i: ReadableStream,
	o: WritableStream,
}

DitzySocket

A WebSocket-like interface to send messages to and receive messages from.

DitzySocket {
	readyState: Number <readonly>,
	textOnly: Boolean,
	send(msg: Uint8Array|String),
	close(): null,
	onclose: Uint8Array|String,
	onmessage: Uint8Array|String,
	onopen: null
}

Binary encoding format

Concepts

Meek

Originally, Meek is a technique emulating stateful connections over HTTP, utilized by Tor for its pluggable transports. It is now generalized to refer to any technique reconstructing stateful connections, regardless of the statefulness of underlying transport.

MIDI

MIDI is a standard for real-time communication between devices. It's originally designed for musical instruments, but has found its places in other fields requiring synchronization and/or automation as well, such as stage lighting systems.

Variable Length Value

Variable Length Value (VLV) is a way of encoding integer values to multiple bytes, utilizing as many bits inside as they want. With VLV, integer values can be as large as they want.

VLV is defined as a part of Standard MIDI File (SMF) Format Specification.

A VLV can take multiple bytes, and all data encoded are stored in Big-Endian format. VLV bytes use the bit before actual values of each byte to indicate whether or not to continue decoding, and the rest to carry actual values.

Examples below.

BitsValue (hex)Value (binary)VLV (binary)VLV (hex)
743010000110100001143
6430100001101000001 000000114103
71c5700011100
01010111
10111000
01010111
b857
7ad4129600001010
11010100
00010010
10010110
11010110
11010000
10100101
00010110
d6d0a516

QUIC

QUIC is a general-purpose transport running on top of UDP, seeking to be a replacement over traditional TCP. It offers various advantages over traditional TCP, with the most notable ones being seamless connection migration and reduced communication latency.

Specification

Structure

Each Ditzy message is formed by directly combining multiple frames together. The structure of each frame is as follows.

LengthValueDescription
1#CommandsCommand ID
1~7(7-bit VLV)Socket ID
1~4(7-bit VLV)Frame ID
1+(7-bit VLV)Payload length
0+(any)Payload data

Socket ID

The socket ID is randomly selected between 0 and 281474976710655 (0xffffffffffff, 248 - 1).

Frame ID

The frame ID is iterated from 0 to 268435455 (0xfffffff, 228 - 1) on the side where connections are initiated. When 268435455 is reached, the message ID is expected to roll back to 0.

Commands

IDs between 0 (0x00) and 31 (0x1f) are reserved for core functionalities. Extenstions are free to utilize any ID between 32 (0x20) and 255 (0xff).

Different commands have different support levels. To meet a certain support level, features of the indicated level must be implemented.

IDCommandLevel
0Socket close1
1Socket open1
2Socket aftertouch2
3Jump2
4Full message send1
5Message acknowledge1
6Error2
7Implementation exclusive3
8Partial message send3
9Partial message send complete3

0: Socket close

Can be initiated bidirectionally.

Response should be exactly the same as request.

Closes a connection. Payload can be used to carry optional arbitrary error messages.

1: Socket open

Can be initiated bidirectionally.

Response should have the same frame ID as request.

Opens a connection. Payload is used to define suggested Socket timeout in milliseconds optionally.

(Optional) If sent from the receiving end, the value contains would be the final timeout value used in the connection.

2: Socket aftertouch

Can be initiated bidirectionally.

Response should have the same frame ID as request.

Challenges a connection. Often used to implement Socket latency tests.

Payload is prefixed with a VLV7 value indicating challenge type, with all remaining bytes containing challenge details.

Types
  • 0: Latency test and keep-alive. No manipulation details field.

3: Jump

Can be initiated bidirectionally.

No responses are needed for jumps, but the receiving end should synchronize frame IDs.

Sends a junk frame. The receiving end should ignore jump messages.

4: Full message send

Can be initiated bidirectionally.

Use type 5 (message acknowledge) to send acknowledgements with the same frame ID.

Sends a full message.

5: Message acknowledge

Can be initiated bidirectionally.

Sends acknowledgements of messages. Additional acknowledgements of tail frame IDs are all encoded via VLV7.

6: Error

Can be initiated bidirectionally.

No response is needed for errors, but the receiving end should synchronize frame IDs.

Sends arbitrary errors without closing the connection.

7: Implementation exclusive

Can be initiated bidirectionally.

Response should have the same frame ID as request.

Implementation exclusive binary commands.

Floaty

Floaty is a Caddy plugin implementing customizable rolling random IDs on a per-host basis, providing easy access via placeholders in Caddy.

Uses include:

  • Loopback prevention
  • Multi-hop debugging
  • Forced time-based rolling sticky hash wherever needed

All with little to no traceability, if the rolling duration is set correctly.

Usage

Caddyfile

In the global section, set Floaty to run before request header processing.

{
	order floaty before header
}

In any of the server blocks, use the floaty directive to prepare the respective rolling random IDs. The syntax is as follows.

floaty [length [rollDuration]] [{
	[fieldId [length [rollDuration]]]
}]

Whenever Floaty is initialized, the placeholder http.floaty would become available within that server block, where placeholders from HTTP handlers are accessible.

Generated ID lengths can be any value between 4 and 96, and out-of-bound values will be clamped into this range. By default, length is set to 8. Longer IDs may cause excessive resource usage.

Roll duration can be set to any value above 10 seconds with millisecond precision, if supported by the Go duration syntax. It's set to 15 minutes by default. A lower rolling duration may cause excessive resource usage.

When a request is received, Floaty will attempt to check if any of the needed request IDs have expired. Only when expired upon receiving a request, will Floaty begin to regenerate a new ID. This will add a little bit of overhead to each request, however it will prevent unnecessary ID rerolls when not in use.

Examples

Adding a response header with a default Floaty ID:

http://:8080 {
	...
	floaty
	header X-Floaty {http.floaty}
	...
}

Adding a request header with a Floaty ID to reverse proxies, while blocking requests with a matching Floaty ID:

http://:8080 {
	...
	floaty {
		instance_id 12 10m
		source_id 12 5m
	}
	...
	@directLoopback {
		header X-Previous-Hop {http.floaty.instance_id}
	}
	@indirectLoopback {
		header X-Source-Hop {http.floaty.source_id}
	}
	respond @directLoopback "Loopback denied" 403
	respond @indirectLoopback "Loopback denied" 403
	...
	reverse_proxy {
		...
		header_up X-Previous-Hop {http.floaty.instance_id}
		header_up ?X-Source-Hop {http.floaty_source_id}
	}
	...
}

gel

⛏ Rolling server bases, batteries included.

Gel is a set of scripts to quickly prepare supported base Linux distributions for use in cloud, aiming to lessen the burden interacting with servers. For Alpine Linux, it comes with a simple OpenRC wrapper to get several systemctl commands working for OpenRC.

Gel is never intended to be used as a base image for containers, as the ease-of-use provided by Gel has little sense to exist in base container images.

Gel is extensively used throughout Lightingale Community's infrastructure.

Flavours

Gel comes with two flavours for each supported base distribution: slim and full.

The full flavour targets all sorts of servers. Unless storage is severely constrained, this is the flavour to go for.

The slim flavour targets container hosts and VM hosts, which barely gets interacted directly, but still requires the ease-of-use found in Gel. It can also be used in other scenarios, if the full flavour contains packages you'd like not to be present on your system.

Full list

SlimFullNameLXC ready?
slimalpalpineAlpine StableNo
slimdebdebianDebian StableYes
slimsuseopensuseopenSUSE TumbleweedNo
slimleapleapsuseopenSUSE LeapYes
slimrockrockyRocky LinuxYes
slimalmaalmaAlmaLinuxYes

Usage & Security

Read here.

Usage

Native

For bare-metal, virtual machines and LXC containers. Do not run native install scripts other than on new machines.

  1. On any of the supported distros, make sure curl is available.
  2. Execute sh <(curl -Ls https://github.com/ltgcgo/gel/releases/latest/download/install.sh).
  3. Connect to the SSH with ssh -p 1122 <serverIP>. User passwords won't change, but SSH settings will. See the SSH section for details.

Containers

Container images are only offered as a convenient way of inspecting the installations.

  1. Spin up one of the available Gel flavours.
    1. Images are available on the Docker Hub if you want to save time. Use podman pull docker.io/ltgc/gel:<flavour> to pull the images.
    2. Or feel free to build the image yourself with ./shx up <flavour>.
  2. Connect to the SSH with ssh -p 1122 [email protected]. The default password is root.

Additional considerations

Alpine Linux

Gel needs the community repo to be enabled in order to function.

openSUSE Leap

doas is not available on the platform. The regular sudo is used instead.

LXC installation

Debian

apt install lxc

openSUSE

zypper in lxc

Rocky Linux/AlmaLinux

dnf install lxc

Alpine

apk add lxc lxcfs lxc-download lxc-bridge

Security

Privilege elevation

To reduce attack surface, Gel will attempt to replace sudo with doas from OpenBSD. By default, only the root user is allowed to use the doas command.

To allow other users to execute the doas command as root, append the following directives to a new line in /etc/doas.conf.

permit keepenv <user> as root

Make sure there is a trailing new line at the end of /etc/doas.conf. If not, doas command will not work.

SSH

The SSH settings will be changed with a relatively more secure one, except for permitting password logins to prevent you from losing access with an unfinished setup.

After finishing the automated Gel setup, do the following to secure your SSH access.

  1. If the password of the root user wasn't set by you, change it to a stronger one.
  2. Add a custom new user, which would be used for SSH logins.
  3. As the newly-created custom user, add the public keys used for SSH authorization.
  4. Keep the current SSH session active, and login as the new user to ensure access to machine is not lost.
  5. Allow the new user to use the doas command and verify. See the Privilege elevation section for details.
  6. Add the new user to the sshuser group, added automatically by the setup script. Example: usermod -aG sshuser <user>.
  7. In /etc/ssh/sshd_config, do the following.
  • Set PermitRootLogin from yes to no.
  • Uncomment AllowGroups and DenyGroups.
  • (optional) Change the listening port from 1122 to another.
  1. Restart sshd with systemctl restart sshd.

Octavia

Octavia is an event-driven multi-standard MIDI state-tracking library.

Features

  • Free, libre and open-source, under GNU LGPL v3.0.
  • Behaves like a real MIDI module.
  • Developed with Firefox and an open Web in mind.
  • Supports 8 ports, 128 channels, 512-voice polyphony maximum.
  • Built-in support of several standards, multiple plug-in cards, and tons of devices.
  • Tells when MIDI programming errors are spotted, reducing chances of faulty programming.
  • Available in JavaScript (browser and Deno).
  • No modification required to run in Tor Browser, Bromite and LibreWolf.
  • Wide support of bank mapping and bitmaps via midi-db.

Dev Talks

We're now hosting a new place to handle development talks! If you don't have a GitHub account, or just prefer to report bugs or give suggestions in a more casual way, feel free to chat with us with links below!

Further documentation

Support table

Implementation

SysEx documentation

API documentation

Audio Effects

Audio effects

Octavia supports tracking a range of audio effects applied on supported targets. For maximum compatibility, Octavia has seven available slots reserved for effect sends, which correspond to reverb, chorus, variation and four insertions in order.

Each slot isn't dedicated to what that slot is primarily used for, but rather allocated and controlled by the CC registers they are assigned to by default (cc91, cc93, cc94, cc16-19). For example, the variation slot (cc94) is taken away by delay effects when in GS mode, while the reverb and chorus slot could be taken away by any effect desired in X5DR or NS5R mode.

Due to varied setups, each effect also isn't just bound to the CC registers they are assigned to. They can also listen on other CC registers, or even multiple if they wish.

Comparison table

Singular effect

Reverb

Yamaha XGGS ReverbGS InsertionKORG AI²
Hall (1, 2, M, L)Hall (1, 2)Hall (1, 2)Hall (normal,
ensemble, concert)
Room (1-3, S, M, L)Room (1-3)Room (1, 2)Room (normal,
large)
Stage (1, 2)Stage (1, 2)Stage
Plate (XG, GM)PlatePlate (wet, dry)
Delay (LCR, LR)DelayDelay (stereo)Delay (stereo)
Echo
Cross DelayPanning DelayDelay (3-tap, 4-tap,
mod, 3D, trem.c.)
Delay (cross, dual, tap 1-3)
Early Reflection
(1, 2)
Early Reflection
(1-3)
Gate (forward, reverse)Gate (forward, reverse,
sweep 1-2)
White Room
Tunnel
Canyon
Basement
Karaoke (1, 2, 3)
Spring

Chorus

Yamaha XGGS ChorusGS InsertionKORG AI²

Delay

Yamaha XGGS DelayGS InsertionKORG AI²

Miscellaneous

Yamaha XGGS InsertionKORG AI²

Dual effect

Mutual

  • X: Yamaha XG
  • G: Roland GS
  • A: KORG AI²
RevChoOvrDstEnhFlnDlyRotPhsAmpCmpAWa
RevA
ChoGGGGGA
OvrGGGXGAXGGXG
DstGGXGAXXX
EnhGGG
FlnGGGGGA
DlyAGAXGAXGAGGAAAA
RotXGXAXX
PhsGA
AmpX
CmpX
AWaXGX

RPN/NRPN values

RPN/NRPN values

Implementation Table

MIDI Implementation Chart

Function Recognized Remarks
Basic Channel Default ✓ 1-16
Changed ✓ 1-16 Supports up to 128 channels.
Note number 0-127
Mode Default 3
Messages ✓ 3, 4
Velocity Note on ✓ 9nV=1-127
Note off ✓ 9nV=0 8n
Aftertouch Key ✓
Channel ✓
Pitchbend ✓ 0-24 semitone steps
14-bit resolution
Control Change 0 ✓ MSB Bank Select
1 ✓ Modulation
2 ✓ Breath
4 ✓ Foot
5 ✓ Portamento Time
6 ✓ MSB (N)RPN Data Commit
7 ✓ Volume
8 ✓ Balance
10 ✓ Pan
11 ✓ Expression
12 ✓ General-purpose effect
13 ✓ General-purpose effect
16 ✓ General-purpose sound
17 ✓ General-purpose sound
18 ✓ General-purpose sound
19 ✓ General-purpose sound
32 ✓ LSB Bank Select
38 ✓ LSB (N)RPN Data Commit
64 ✓ Sustain (Hold)
65 ✓ Portamento
66 ✓ Sostenuto
67 ✓ Soft Pedal
Store only
68 ✓ Legato
Store only
69 ✓ Hold 2
Store only
70 ✓ Timbre Variation
Store only
71 ✓ Resonance
72 ✓ Release Time
73 ✓ Attack Time
74 ✓ Brightness
75 ✓ Decay Time
76 ✓ Vibrato Rate
77 ✓ Vibrato Depth
78 ✓ Vibrato Delay
84 ✓ Portamento Control
91 ✓ Reverb
92 ✓ Tremelo
93 ✓ Chorus
94 ✓ Variation
95 ✓ Phaser
96 ✓ Data Increment
97 ✓ Data Decrement
98 ✓ LSB NRPN
99 ✓ MSB NRPN
100 ✓ LSB RPN
101 ✓ MSB RPN
120 ✕ All Sound Off
121 ✓ All Controllers Reset
123 ✓ All Notes Off
124 ✕ Omni Off
Same as cc123
125 ✕ Omni On
Same as cc123
126 ✓ Mono
127 ✓ Poly
128 ✓ Dry level (internal)
129 ✓ VL Breath Strength (internal)
130 ✓ VL Pressure (internal)
131 ✓ VL Embouchure (internal)
132 ✓ VL Tonguing (internal)
133 ✓ VL Scream (internal)
134 ✓ VL Breath Noise (internal)
135 ✓ VL Growl (internal)
136 ✓ VL Throat Formant (internal)
137 ✓ VL Harmonic Enhancer (internal)
138 ✓ VL Damping (internal)
139 ✓ VL Absorption (internal)
140 ✓ VL Filter (internal)
141 ✓ VL Amplitude (internal)
142~149 ✓ DX Carrier Level 1~8 (internal)
150~157 ✓ DX Modulator Level 1~8 (internal)
Program Change 0-127
System Exclusive General MIDI ✓
General MIDI rev. 2 ✓
YAMAHA XG ✓
YAMAHA PLG-150AP ✕
YAMAHA PLG-150AN ✕
YAMAHA PLG-150DR/PC ✕
YAMAHA PLG-150DX ✕
YAMAHA PLG-150PF ✕
YAMAHA PLG-100SG ✓
YAMAHA PLG-150VL ✓
YAMAHA TG300 ✓
Roland GS ✓
Roland SD ✓
Roland C/M ✓
KORG NS5R ✓
KORG N1R ✓ Redirected to NS5R
KORG X5D(R) ✓
KORG 05R/W ✓
KAWAI GMega ✓ Also known as KAWAI K11
AKAI SG01 ✓
CASIO GZ-50M ✓
ALESIS NanoSynth ✕
System Common Song position ✕
Song select ✕
Tune ✕
System RealTime Clock ✕ No action defined
Start ✕ No action defined
Continue ✕ No action defined
Stop ✕ No action defined
Aux messages Local ON/OFF ✕
Active Sense ✕ No action defined

SysEx Instructions

Supported SysEx Instructions

  • ✓: Supported
  • -: Partially supported
  • ✕: Not supported
  • ?: Unknown
  • (blank): N/A

Mutual instructions

GMGM2MT-32XGGS05R/WX5DNS5RSDGMegaGMega LXSG-01GZ-50M
System reset✓✓✓✓✓✓✓✓✓
Master setup✓✓✓✓✓✓✕✓✓
Reverb setup✓✓✓✓✓✓✓✓
Chorus setup✓✓✓✓✓✓✓✓
Variation setup?✓✓
Part setup?✓✓✓✓✓✓✓✓
Equalizer✓✓✕
EFX / insertion-✓³-✓
Bitmap display¹✓✓✓
Text display²✓✓✓✓
Drum setup?✓✓✓✕✕✓✕✕✕
  1. Support in GS is called "frame draw", and with multi-page support.
  2. Called "letter display" in XG, and "text insert" in GS.
  3. GS only has "delay" effect occupying the space of variation setup.

Device-specific instructions

Roland MT-32

  • Temporary Patch Setup
  • Temporary Drum Setup
  • Temporary Timbre Setup
  • Device Patch Setup
  • Device Timbre Setup
  • Patch Memory Write
  • Timbre Memory Write
  • System

Yamaha MU1000

  • A/D Part Setup
  • A/D Mono/Stereo
  • System

Yamaha PLG-100SG

  • Master Setup
  • Part Setup
  • PhoneSEQ Setup
  • Lyrics Information Setup

Yamaha PLG-150DX

  • Master Setup
  • Part Setup
  • DX Voice Param
  • DX Voice Additional Param

Yamaha PLG-150VL

  • Master Setup
  • Current Voice Parameters
  • Part Setup

Roland SC-88

  • Single/dual Mode

KORG X5D

  • All Program Dump
  • All Combi Dump
  • Extended Multi Dump

KORG NS5R

  • Mode Switch
  • All Program Dump
  • All Combi Dump
  • Extended Multi Dump

Targets

Supported targets

General support table

The following list of targets have their support by Octavia status presented in a table. A target can be a model, a plugin board, a lineup, or a standard.

A supported standard may also have a list of specific target models listed.

For specific SysEx support range, refer to Supported SysEx Instructions;

VendorTargetTypeBankSysEx
MMAGMS✓✓
MMAGM2S✓✓
RolandMT-32S✓✓
RolandGSS✓✓
RolandSDS✓✓
YAMAHATGL✓✓
YAMAHAXG¹S✓✓
YAMAHAPLG-150ANP✓✕
YAMAHAPLG-150APP✓✕
YAMAHAPLG-150DRP✓✕
YAMAHAPLG-150DXP✓✕
YAMAHAPLG-150PCP✓✕
YAMAHAPLG-150PFP✓✕
YAMAHAPLG-150VLP✓✓
YAMAHAPLG-100SGP✓✓
YAMAHAS90 ESL✓✓
YAMAHAMotif ESL✓✓
KORGAG-10M✓✓
KORG05R/WL✓✓
KORGX5DRL✓✓
KORGNS5R/NX5RL✓✓
KAWAIGMegaL✓✓
KAWAIGMega LXM✓✓
AKAISG01kM✓✓
CASIOGZ-50MM✓✓
ALESISNanoSynthM✕✕
  1. Octavia implements XG level 3.0 or later, and XG version 2.0 or later.

Specific targets

Roland MT-32

TargetTypeStatus
MT-32M✓
MT-100M-
CM-32LM✓
CM-32LNM-
CM-64M-
CM-500M-
LAPC-IM-
LAPC-NM-
RA-50M-
E-20M-

Roland GS

TargetTypeStatus
CM-300M✓
SC-55L✓
SC-88L✓
SC-88 ProL✓
SC-8850L✓
SD-20M-
SD-35M-
SD-50M-
SD-80M-
SD-90M-
SK-50L-

Yamaha TG

TargetTypeStatus
TG55M-
TG33M-
TG77M-
TG100M-
TG500M-
TG300M✓

Yamaha XG

TargetTypeStatus
DBXG50M✓
DBXG51M✓
DBXG60M-
MU5M✓
MU80M✓
MU50M✓
MU90L✓
MU10M✓
MU100L✓
MU15M✓
MU128L✓
MU1000L✓
MU2000L✓
MU500M✓
PLG100-XGP✓
QY700M✓
QY70M✓
QY100M✓
SW60XGM-
SW1000XGM-
S-YXG50M✓
S-YXG70M✓
S-YXG100M✓
S-YXG2006LEM✓

state.mjs API

All constants and interfaces documented here are guaranteed to work, and very likely not subject to further changes.

Constants

MIDI modes

Octavia is compatible with a range of modes on MIDI synthesizers. A list of supported modes to their respective keys is available below.

  • ?: The default "nothing" mode. Octavia will try to detect the correct mode.
  • gm: General MIDI mode.
  • gs: Roland GS mode.
  • xg: Yamaha XG mode. Compatible with TG-100 and TG-300.
  • g2: General MIDI Level 2 mode.
  • sd: Roland SD mode.
  • mt32: Roland MT-32 mode.
  • ns5r: KORG NS5R mode. Compatible with NX5R, and has limited compatibility with KORG N1R and N5.
  • x5d: KORG X5D(R) mode. Compatible with AG-10.
  • 05rw: KORG 05R/W and KORG X5 mode. Compatible with AG-10.
  • k11: Kawai GMega and Kawai K11 mode.
  • sg: Akai SG mode.
  • krs: KORG KROSS 2 mode.
  • s90es: Yamaha S90 ES mode.
  • motif: Yamaha Motif ES mode.

MIDI event types

  • 8: Note off
  • 9: Note on
  • 10: Note aftertouch, a.k.a. polyphonic aftertouch
  • 11: Channel controller change
  • 12: Channel program change
  • 13: Channel aftertouch
  • 14: Channel pitch bend
  • 15: System exclusive message

allocated

ccToPos

Interfaces

OctaviaDevice

General MIDI Extended

GME, short for General MIDI Extended, is a standard based off General MIDI level 1, which emphasizes on slightly extending the ability of General MIDI while not being too demanding. General MIDI Extended can be considered as a summarization of the common functionality among all GM-compatible synthesizers, and should be the baseline of all contemporary General MIDI-compatible synthesizers.

Requirements

Any GME-compliant synthesizer must adhere all requirements listed below.

  • Has at least 24 oscillators available simultaneously (polyphony), which must either be...
    • At least 24 fully dynamically allocated oscillators for both melodic and percussion sounds.
    • At least 16 dynamically allocated oscillators for melodic sounds, 8 for percussion sounds.
  • Supports all 16 MIDI channels, which...
    • Can play arbitrary number of voices within the polyphony limit.
    • Can change to a different instrument.
    • Channel 10 is set to percussion by default.
  • Correctly responds to listed required events, CC and RPN.
  • Has all voices listed in the required voice list.
  • Has drum kits following the required drum note mapping.
  • Correctly responds to required System Exclusive messages.

Voice list

Drum voices

Drum kits will reside on MSB 124, and all level 1 kits will also reside on MSB 120.

The above portion is not yet decided.

PC#Drum Kit NameLevel
000Standard Kit1
001Standard Kit 22
002Standard Kit 34
003Standard Kit L/R5
008Room Kit1
009Hip Hop Kit3
010Jungle Kit3
011Techno Kit4
012Dark Room Kit5
013House Kit4
014Techno Kit High4
015Techno Kit Low4
016Power Kit/Rock Kit1
017Rock Kit 23
018Rock Kit 34
019R&B Kit4
024Electro Kit1
025Analog Kit1
026Analog Kit 23
027Dance Kit3
028Rave Kit5
030Apogee Kit4
031Perigee Kit4
032Jazz Kit2
033Jazz Kit L/R5
040Brush Kit1
041Brush Kit 24
048Orchestra Kit1
049Ethnic Kit2
050Sakura Kit5
051China Kit5
052Asian Kit3
053Orchestra Kit Y5
054Gamelan Kit5
055Gamelan Kit 25
056SFX Kit2
057SFX Kit Y2
058SFX Kit Y 22
060SFX Kit 25
064Percussion Kit2

Melodic voices

Piano

PC#Voice Name
000Grand Piano
001Bright Grand Piano
002Electric Grand Piano
003Honky-tonk Piano
004Electric Piano
005Chorused Electric Piano
006Harpsichord
007Clavichord

Chromatic percussion

PC#Voice Name
008Celesta
009Glockenspiel
010Music Box
011Vibraphone
012Marimba
013Xylophone
014Tubular Bells
015Dulcimer1
  1. Some implementations may swap Dulcimer out with Santur.

Organ

PC#Voice Name
016Drawbar Organ
017Percussive Organ
018Rock Organ
019Church Organ
020Reed Organ
021French Accordion
022Harmonica
023Tango Accordion

Guitar

PC#Voice Name
024Nylon Acoustic Guitar
025Steel Acoustic Guitar
026Jazz Electric Guitar
027Clean Electric Guitar
028Muted Electric Guitar
029Overdriven Guitar
030Distortion Guitar
031Guitar Harmonics

Bass

PC#Voice Name
032Acoustic Bass
033Fingered Bass
034Picked Bass
035Fretless Bass
036Slap Bass 1
037Slap Bass 2
038Synth Bass 1
039Synth Bass 2

Solo strings/orchestra

PC#Voice Name
040Violin
041Viola
042Cello
043Contrabass
044Tremelo Strings
045Pizzcato Strings
046Harp
047Timpani

Ensemble strings/orchestra

PC#Voice Name
048Ensemble Strings
049Ensemble Slow Strings
050Synth Strings 1
051Synth Strings 2
052Choir Aahs
053Voice Oohs
054Synth Voice
055Orchestra Hit

Brass

PC#Voice Name
056Trumpet
057Trombone
058Tuba
059Muted Trumpet
060French Horn
061Brass Section
062Synth Brass 1
063Synth Brass 2

Reed

PC#Voice Name
064Soprano Saxophone
065Alto Saxophone
066Tenor Saxophone
067Baritine Saxophone
068Oboe
069English Horn
070Bassoon
071Clarinet

Pipe

PC#Voice Name
072Piccolo
073Flute
074Recorder
075Pan Flute
076Blown Bottle
077Shakuhachi
078Whistle
079Ocarina

Synth lead

PC#Voice Name
080Square Wave Lead
081Sawtooth Wave Lead
082Synth Calliope Lead
083Chiffer Lead
084Charang Lead
085Voice Lead
086Fifth Sawtooth Lead
087Bass & Lead

Synth pad

PC#Voice Name
088New Age Pad1
089Warm Pad
090Poly Synth Pad
091Choir Pad
092Bowed Glass Pad
093Metal Pad
094Halo Pad
095Sweep Pad
  1. Or "Fantasia Pad".

Synth melodic sound effects

PC#Voice Name
096Ice Rain
097Soundtrack
098Crystal
099Atmosphere
100Brightness
101Goblins
102Echo Drops
103Sci-Fi

Ethnic

PC#Voice Name
104Sitar
105Banjo
106Shamisen
107Koto
108Kalimba
109Bagpipe
110Fiddle
111Shanai

Percussive

PC#Voice Name
112Tinkle Bell
113Agogo
114Steel Drums
115Woodblock
116Taiko Drum
117Melodic Tom
118Synth Drum
119Reverse Cymbal

Sound effects

PC#Voice Name
120Guitar Fret Noise
121Breath Noise
122Seashore
123Bird Tweet
124Telephone Ring
125Helicopter
126Applause1
127Gunshot
  1. Can be optionally extended as a menu voice, with examples including Stadium!!! in KORG AI2 lineup.

Drum note mapping

  • Regular: Required.
  • Italic: Optional. If not defined, the note will behave the same as in Standard Kit.
  • ←: Same as Standard Kit.
PC# 0 1 8 16 24 25 32 40 48
Kit Standard Kit Standard 2 Kit Room Kit Power/Rock Kit Electro Kit Analog Kit Jazz Kit Brush Kit Orchestra Kit
# Note
35 B~1 Tight Kick Tight Kick 2 ← Rock Tight Kick Electro Tight Kick Analog Tight Kick Jazz Tight Kick Jazz Tight Kick Jazz Kick
36 C~2 Kick Kick 2 Room Kick Rock Kick Electro Kick Analog Kick Jazz Kick Brush Kick Concert Bass Drum
37 C#2 Side Stick ← ← ← ← Analog Side Stick ← ← ←
38 D~2 Snare Snare 2 Room Snare Rock Snare Electro Snare Analog Snare Jazz Snare Brush Tap Concert Snare Drum
39 Eb2 Hand Clap ← ← ← ← ← Jazz Hand Clap Brush Slap Castanet
40 E~2 Tight Snare Tight Snare 2 Room Tight Snare Rock Tight Snare Electro Tight Snare Analog Tight Snare ← Brush Swirl Concert Snare Drum
41 F~2 Floor Tom Lo ← Room Floor Tom Lo Rock Floor Tom Lo Electro Floor Tom Lo Analog Floor Tom Lo Jazz Floor Tom Lo Brush Floor Tom Lo Timpani F
42 F#2 Hi-Hat Closed Hi-Hat Closed 2 Room Hi-Hat Closed Room Hi-Hat Closed Hi-Hat Closed 2 Analog Hi-Hat Closed Jazz Hi-Hat Closed Brush Hi-Hat Closed Timpani F#
43 G~2 Floor Tom Hi ← Room Floor Tom Hi Rock Floor Tom Hi Electro Floor Tom Hi Analog Floor Tom Hi Jazz Floor Tom Hi Brush Floor Tom Hi Timpani G
44 Ab2 Hi-Hat Pedal Hi-Hat Pedal 2 ← ← ← Analog Hi-Hat Closed Hi ← Brush Hi-Hat Pedal Timpani G#
45 A~2 Low Tom ← Room Low Tom Rock Low Tom Electro Low Tom Analog Low Tom Jazz Low Tom Brush Low Tom Timpani A
46 Bb2 Hi-Hat Open Hi-Hat Open 2 Room Hi-Hat Open Room Hi-Hat Open Hi-Hat Open 2 Analog Hi-Hat Open Jazz Hi-Hat Open Brush Hi-Hat Open Timpani A#
47 B~2 Mid Tom Lo ← Room Mid Tom Lo Rock Mid Tom Lo Electro Mid Tom Lo Analog Mid Tom Lo Jazz Mid Tom Lo Brush Mid Tom Lo Timpani B
48 C~3 Mid Tom Hi ← Room Mid Tom Hi Rock Mid Tom Hi Electro Mid Tom Hi Analog Mid Tom Hi Jazz Mid Tom Hi Brush Mid Tom Hi Timpani C
49 C#3 Cymbal Crash 1 ← ← ← ← Analog Cymbal Crash ← Brush Cymbal Crash Timpani C#
50 D~3 High Tom ← Room High Tom Rock High Tom Electro High Tom Analog High Tom Jazz High Tom Brush High Tom Timpani D
51 Eb3 Cymbal Ride 1 ← ← ← ← ← ← Brush Cymbal Ride Timpani D#
52 E~3 Chinese Cymbal ← ← ← Reverse Cymbal ← ← ← Timpani E
53 F~3 Bell Ride ← ← ← ← ← ← Brush Bell Ride Timpani F 2
54 F#3 Tambourine ← ← ← ← ← ← ← ←
55 G~3 Cymbal Splash ← ← ← ← ← ← ← ←
56 Ab3 Cowbell ← ← ← ← Analog Cowbell ← ← ←
57 A~3 Cymbal Crash 2 ← ← ← ← ← ← ← Concert Cymbal 2
58 Bb3 Vibraslap ← ← ← ← ← ← ← ←
59 B~3 Cymbal Ride 2 ← ← ← ← ← ← ← Concert Cymbal
60 C~4 Bongo Hi ← ← ← ← ← ← ← ←
61 C#4 Bongo Lo ← ← ← ← ← ← ← ←
62 D~4 Muted Conga Hi ← ← ← ← Analog Conga Hi ← ← ←
63 Eb4 Open Conga Hi ← ← ← ← Analog Conga Mid ← ← ←
64 E~4 Conga Lo ← ← ← ← Analog Conga Lo ← ← ←
65 F~4 Timbale Hi ← ← ← ← ← ← ← ←
66 F#4 Timbale Lo ← ← ← ← ← ← ← ←
67 G~4 Agogo Hi ← ← ← ← ← ← ← ←
68 Ab4 Agogo Lo ← ← ← ← ← ← ← ←
69 A~4 Cabasa ← ← ← ← ← ← ← ←
70 Bb4 Maracas ← ← ← ← Analog Maracas ← ← ←
71 B~4 Short Whistle Hi ← ← ← ← ← ← ← ←
72 C~5 Long Whistle Lo ← ← ← ← ← ← ← ←
73 C#5 Short Guiro ← ← ← ← ← ← ← ←
74 D~5 Long Guiro ← ← ← ← ← ← ← ←
75 Eb5 Claves ← ← ← ← Analog Claves ← ← ←
76 E~5 Woodblock Hi ← ← ← ← ← ← ← ←
77 F~5 Woodblock Lo ← ← ← ← ← ← ← ←
78 F#5 Muted Cuica ← ← ← ← ← ← ← ←
79 G~5 Open Cuica ← ← ← ← ← ← ← ←
80 Ab5 Muted Triangle ← ← ← ← ← ← ← ←
81 A~5 Open Triangle ← ← ← ← ← ← ← ←
82 Bb5 Shaker ← ← ← ← ← ← ← ←
83 B~5 Jingle Bell ← ← ← ← ← ← ← ←
84 C~6 Bell Tree Bar Chimes ← ← ← ← ← ← ←

Events, CC and RPN

Events

Assembly

Except System Exclusive messages, the first byte of each MIDI event defines the event type and target channel. The first four bits define the event type, with the last four bits defining the target channel.

Types

ID#IDType
80x8Note off
90x9Note on
100xaNote aftertouch (PAT)
110xbControl change
120xcProgram change
130xdChannel aftertouch (CAT)
140xePitch bend
150xfSystem messages

System message types

ID#IDTypeOptional
2400xf0System Exclusive (Start of Exclusive)No
2470xf7System Exclusive (End of Exclusive)No
2480xf8ClockYes
2500xfaStartYes
2510xfbContinueYes
2520xfcStopYes
2540xfeActive sensingYes
2550xff(Line invalid) Meta eventsNo

Types

Control Changes

Mapping

Data

ID#IDTypeRangeOptional
00x00MSB Bank Select0-127No
320x20LSB Bank Select0-127No
60x06MSB Data Commit0-127No
380x26LSB Data Commit0-127No
980x62LSB NRPN0-127No
990x63MSB NRPN0-127No
1000x64LSB RPN0-127No
1010x65MSB RPN0-127No
960x60RPN Increase0-127No
970x61RPN Decrease0-127No

Voice

ID#IDTypeRangeOptional
10x01Modulation0-127No
50x05Portamento Time0-127No
70x07Volume0-127No
100x0aPan0-127No
110x0bExpression0-127No
640x40Sustain (Hold)0-127No
650x41Portamento Switch0-127No
660x42Sostenuto0-127No
670x43Soft Pedal0-127No
710x47Resonance0-127No
720x48Release Time0-127No
730x49Attack Time0-127No
740x4aBrightness0-127No
750x4bDecay Time0-127Yes
760x4cVibrato Rate0-127Yes
770x4dVibrato Depth0-127Yes
780x4eVibrato Delay0-127Yes
840x54Portamento Source0-127No
910x5bEffect (Reverb)0-127No
920x5cEffect (Tremelo)0-127Yes
930x5dEffect (Chorus)0-127No
940x5eEffect (Variation)0-127No
950x5fEffect (Phaser)0-127No

Modes

ID#IDTypeRangeOptional
1200x78All Sound Off0No
1210x79Reset All Controllers0No
1230x7bAll Note Off0No
1240x7cOmni Off0Yes
1250x7dOmni On0Yes
1260x7eMono0-16No
1270x7fPoly0No

Types

Registered Parameter Numbers

Non-registered Parameter Numbers

Warning

This section is optional.

System Exclusive

Painted Palette

Painted Palette is a headless bot implemented purely in JavaScript, which helps pixel placements on r/place. It is developed for the My Little Pony factions, but can work for any other faction with modification.

If the codebase isn't modified, in auto mode, Painted Palette runs on a defensive stance by default - as long as pixels covered by the template aren't badly damaged, it barely activates. If in manual mode, Painted Palette only places pixels when the user commands or schedules a pixel placement.

Features

  • Extremely fast to build, fast and easy to deploy for anyone. IT prowness is not a problem.
  • No dependency compiling before running.
  • Fully-unattended automated updates.
  • Relatively low on resources.
  • Native support for multi-account deployments. (less than 10 per IP address)

Installation

Warning

Node.js on Windows does not respect proxy settings. If proxies are needed, switch to Deno instead.

With an acceptable Internet connection, the whole installation process should not take more than 20 seconds. On POSIX systems, the figure is even lower.

If you're up for the task, feel free to contribute, and expand our horizon of OS support!

Windows

  1. Download the latest version of node_windows.zip.
  2. Extract node_windows.zip to an appropriate folder of your liking.

Linux, Android, macOS

  1. Ensure bash, curl and unzip are available.
  2. Assign export VARIANT=node.
  3. Make sure you have either Node.js 18 or Node.js 19 installed.
  4. Run bash <(curl -Ls https://github.com/ltgcgo/painted-palette/raw/main/src/bash/install.sh).

Running

Warning

Despite our efforts on bot detection evasion, when not in manual mode, running the bot on your main is generally considered a bad idea. Please use disposable alts when in auto mode.

For more advanced usage, please refer to command line docs.

Windows (default GUI only)

  • Double-click webui.cmd, and click on the link it provides. Should point to 127.0.0.1:14514 by default.
    • If the browser displays an error page, run winFix.cmd first, then restart gui.cmd to see if the problem goes away.

Linux, Android, macOS

  • Run ./palette-bot batch, and click on the link it provides.
  • Do you have Tor installed on your system? If yes and you're using Deno, run ./palette-tor batch to use it without the tedious configuration process!
  • Are you running Painted Palette with Deno on Linux? If yes, run ./palette-proxy batch to connect to public proxy pools with ease!

Windows (CLI)

  • Open a terminal session where webui.cmd is located.
  • Run with .\node.exe node.js <arguments>.

Podman/Docker

  • Clone the repo via git clone https://github.com/ltgcgo/painted-palette.git palette.
  • Switch into oci via cd ./palette/oci.
  • Run docker-compose up -d if on Docker, or podman-compose up -d if on Podman.

Open Source

Painted Palette is a piece of open-source software, licensed under GNU GPL 3.0.

Source code: GitHub

Web UI

WIP

Command line

The Windows build does not ship with a helper like ./palette-bot . As such, please replace ./palette-bot with node node.js or deno run --allow-read --allow-write --allow-net deno.js .

With Deno or Bun, if you need to specify custom proxies, define the https_proxy environment variable (e.g. https_proxy=http://127.0.0.1:4444/). There are direct proxy integrations available on Linux and Android, which can be used by replacing ./palette-bot with either ./palette-proxy for public proxy pools, or ./palette-tor for Tor.

Environment variables

  • BIND_ADDRESS: Define a bind address. Do not include ports.
  • HTTP_PROXY: Used by Deno and Bun to connect to upstream proxies.
  • HTTPS_PROXY: Same as above. Must be the same as HTTP_PROXY.
  • NO_UPDATE: Set to 1 to disable the automatic updater.
  • PORT: Set the port PP listens for REST API calls. Used in ./palette-bot ctl.
  • SLEEP: Set to 1 to behave as if ./palette-bot ctl sleep is run.
  • TEMPLATE_URL: Customize the pointer URL.

./palette-bot help

Prints help messages.

./palette-bot paint

Deprecated and not recommended. Paint on Reddit with given credentials.

Format: ./palette-bot paint <username> <password> <otp>

Examples:

  • Direct login: ./palette-bot paint myCoolName myGoodPassword
  • Direct login with 2FA codes: ./palette-bot paint myCoolName myGoodPassword 114514

./palette-bot pixel

Removed. Paint on VKontakte with given credentials.

Same format as ./palette-bot paint.

./palette-bot test

Deprecated and not recommended. Paint on the test server with given credentials.

Same format as ./palette-bot paint.

./palette-bot batch

Start a batch mode server for account management, complete with Web UI and REST API.

Since version 0.0.16, manual mode became the default - pixel placements require user interaction, and only a single account is allowed.

Format: ./palette-bot batch <port>

./palette-bot ctl

Send commands to a running batch server. Define the target port which the batch server listens on with the environment variable PORT.

Format: ./palette-bot ctl <subcommand> <...args>

Subcommands

r/place 2023

Warning

Information on this page is outdated.

Written on 22nd June 2023

Warning

r/place 2023 did not happen on 1st April or 23rd June.

You know the drill: r/place 2023 is coming. So we prepared a list of FAQs, for you as a brony/pegasister to bootstrap your knowledge!

What is r/place?

r/place is a social experiment run by Reddit, where every participant gets to place coloured pixels with a defined cooldown. With itself categorized as a form of "pixel battle", it is by far the largest pixel battle held across the globe.

With only the power of a single person, not much could be created. However, with the power of factions, there's no such thing as "impossible"!

Why should I participate?

Although r/place isn't an annual event, Reddit held r/place last year (2022) also. And last year, we suffered dozens of raids, most of them lost due to a lack of firepower, and were able to recover solely because attackers went inactive eventually, either due to sleeping or due to recess between raids. We hope we could stop the same from happening again.

We prepared for r/place in advance this year, but with multi-account and automated pixel placement banned in the main faction, all while protests regarding Reddit APIs going in full swing, the expected firepower looks even dimmer. Despite the ongoing Reddit API fiasco, we desperately need everyone we can hopefully get, to extend our firepower as much as possible for all possible defense. Please consider participating the event!

When is it expected to happen?

On 23rd June 2023, Reddit's anniversary before its IPO. The exact time may vary, but it is rumored to happen at around 13:00 UTC.

How do I participate as a My Little Pony fan?

Lucky for us, a group of enthusiastic bronies established a faction before r/place even began, which became the main MLP faction of r/place 2023. But unlucky for us, said faction recently got splintered.

Why the splinter?

The initial trigger was an announcement on 18th June, regarding ban on all forms of automatic pixel placement, alongwith joining an unknown alliance called "P3ACE".

The ban alone did directly result in the creation of a faction, but it was a series of indications and later dealings sending the splinter onto a seemingly irreversible course: lack of transparency regarding joining the alliance, single parties meddling and forced the join, reluctance of communication regarding multi-account and automated pixel placement, with certain mods outright shunning and diverting arguments, all while removing downvotes on that specific announcement. All these enraged some parties, setting the splinter in stone.

The current splinter does not dwindle the firepower MLP as a whole possesses, as both use the very same template.

What about the pros and cons of automated pixel placements?

Pros

  • Relatively low resource consumption, good for low-end devices
  • Does not require you to stare at a screen and clicking your mouse for hours end
    • Does not hinder you from your work
    • Allows you to sleep as usual

Cons

  • If only with automated placements, one cannot experience the event to its fullest
  • Shamed by some people
  • "Does not believe in friendship"

How do existing implementations of automation fit?

  • Browser overlay: Auto-clicker is removed, and tab freeze circumvention became borked. Auto-focus and automatic colour picking still exist, but every pixel placement now requires user interactions.
  • PonyPixel (Python headless): Retired.
  • Painted Palette (JavaScript headless): A seperate manual-only mode is planned, but is largely unhindered.

How should I join the factions?

With the main faction prohibited discussions regarding several topics, the splintered-off faction offers a supplemental and more libre place where said topics are likely not forbidden. If you are fine with all the bureaucracy issues in the main faction, and agrees to stare at a screen for hours to place every single pixel manually, you can join the main faction. Otherwise, joining the splintered-off faction is much recommended.

Since Painted Palette by itself is a somewhat independent project, it has an additional place for dev talks unrelated to the splinter.

raven

💨 Lightning-fast intuitive typing.

Target scripts

Usage

m17n

m17n is an IME library for mapped stream conversion of characters. To develop schemas for m17n, read the database tutorial.

m17n is included in both IBus (Intelligent Input Bus) and fcitx5.

Linux

  • Get the required .mim files.
  • Check if the IME framework of your system supports m17n. Most Linux desktop distros with IBus has m17n support included by default.
  • Check if directory ~/.m17n.d/ exists for the current user. If not, create it via mkdir ~/.m17n.d/.
  • Copy the .mim files you want to use to ~/.m17n.d.
  • Restart your IME framework.
    • If on IBus, run ibus restart.

Android

Warning

No input methods on Android support m17n currently. For its possible support on Android, please check out the issue in the fcitx5-android project.

Rime

Rime is an IME framework for implementing custom input schemas for different languages. To develop schemas for Rime, read here (machine translation required).

Rime is supported on Linux via IBus, Windows and macOS. Platform support is extended with forks, e.g. for fcitx5 (fcitx-rime), Android (Trime) and iOS (Hamster, iRime).

The official Rime documentation is only available in Orthodox Chinese.

Linux

  • Get the required .yaml files. Check for files ending in .schema.yaml, .dict.yaml and .custom.yaml.
  • Copy the .yaml files to ~/.config/ibus/rime/.
  • (Optional) Customize the new schema as you see fit.
  • Enable the new schema in ~/.config/ibus/rime/default.custom.yaml.
  • Redeploy Rime via touch ~/.config/ibus/rime/; ibus restart.

Windows

  • Get the required .yaml files. Check for files ending in .schema.yaml, .dict.yaml and .custom.yaml.
  • Copy the .yaml files to %APPDATA%\\Rime.
  • (Optional) Customize the new schema as you see fit.
  • Enable the new schema in %APPDATA%\\Rime\\default.custom.yaml.
  • Redeploy Rime via start menu or right-click menu of the taskbar icon.

Android

fcitx5-android

TBD.

Trime

TBD.

Key map

Consonants

KeymapARUR/FAUG
aا (a)ا (a)ا (a)
bب (b)ب (b)ب (b)
pÙ¾ (p)Ù¾ (p)
tت (t)ت (t)ت (t)
TÙ¹ (á¹­)
Cث (ṯ)ث (s)
jج (j)ج (j)ج (j)
cچ (c)چ (ch)
hح (ḥ)ح (h)
Kخ (ḫ)خ (x)خ (x)
dد (d)د (d)د (d)
Dڈ (ḍ)
Zذ (ḏ)ذ (z)
rر (r)ر (r)ر (r)
Rڑ (ṛ)
zز (z)ز (z)ز (z)
Xژ (zh)ژ (zh)
sس (s)س (s)س (s)
xش (š)ش (ś)ش (sh)
Sص (ṣ)ص (s)
Jض (ḍ)ض (z)
vØ· (á¹­)Ø· (t)
Vظ (ẓ)ظ (z)
eع (ʿ)ع (')
Gغ (ġ)غ (ġ)غ (gh)
fف (f)ف (f)ف (f)
qق (q)ق (q)ق (q)
kك (k)ک (k)ك (k)
gÚ¯ (g)Ú¯ (g)
lل (l)ل (l)ل (l)
mم (m)م (m)م (m)
nن (n)ن (n)ن (n)
Nں (◌̃)ڭ (ng)
oه (h)ه (FA), ہ (UR) (h)ھ (h)
wو (w)و (w/ū)ۋ (w)
HÚ¾ (-h)
uء (ʾ)ء (')ئ
iي (y)ی (y/ī)ي (y)
yے (ē)ە (e)
ى (ā)
و (o)
ۇ (u)
ۆ (ö)
ۈ (ü)
ې (ë)
ى (i)

Vowels

Letters with hamza

KeymapARUR/FAUG
Aآ (ā)آ (ā)
أ (ʾa/ʾu)
إ (ʾi)
ؤ
ࢨ

Numbers

Arabic and Persian numerals have separate codepoints, despite only three of them (4, 5, 6) look different. Urdu numerals share the same codpoint as the Persian ones, but three of them (4, 6, 7) should look different with proper language settings.

KeymapARUR/FAUG
0Ù Û°Ù 
1Ù¡Û±Ù¡
2Ù¢Û²Ù¢
3Ù£Û³Ù£
4Ù¤Û´Ù¤
5Ù¥ÛµÙ¥
6Ù¦Û¶Ù¦
7Ù§Û·Ù§
8Ù¨Û¸Ù¨
9Ù©Û¹Ù©

Punctuations

English phonetic alphabets

As per effort of decreasing the learning curve as much as possible, all English phonetical alphabets share the same set of key map.

Included alphabets

British English Phonetic Alphabet

BEPA is an adaptation of International Phonetic Alphabet, optimized to represent the sounds of British English, and by extension all of its variants.

Shavian alphabet

The Shavian alphabet is a constructed alphabet aims to permit efficient writing and spelling for British English Received Pronunciation.

Deseret alphabet

Warning

Due to a lack of several vowels, there are no plans to support the Deseret alphabet as of yet.

The Deseret alphabet is a constructed alphabet developed to be used in an English-language spelling reform for American English.

Key map

Keys are ordered via BEPA.

Vowels

Vowels require at most two keys.

Short vowels

SequenceBEPAShavianDeseretExample
Aæ𐑨𐐰cat
e ehɛ𐑧𐐯bet
Ee EEe𐑧𐐯bet
i ihɪ𐑦𐐮fit
o ohɒ𐑪𐐱hot
a ahʌ𐑳𐐲cut
u uhʊ𐑫𐐳cook
E Ehə𐑩𐐲lover
Ii𐑦𐐨
Uu𐑫𐐭

Long vowels

SequenceBEPAShavianDeseretExample
iiiː𐑰𐐨eat
ooɔː𐑷𐐫all
eeɜː𐑻𐐲𐑉her
uuuː𐑵𐐭who
aaɑː𐑭𐐪car

Diphthongs

SequenceBEPAShavianDeseretExample
eieɪ𐑱𐐩cake
aiaɪ𐑲𐐴like
oiɔɪ𐑶𐑎oil
euəʊ𐑴𐐬coat
ouoʊ𐑴𐐬hope
auaʊ𐑬𐐵how
irɪə𐑾𐐮𐐲ear
erɛə𐑺𐐯𐑉air
urʊə𐑫𐑩𐐳𐐲sure

Shavian compatibles

SequenceBEPAShavianDeseretExample
aRɑːr𐑸𐐪𐑉art
oRɔːr𐑹𐐫𐑉/𐐬𐑉ore
eRɛər𐑺𐐯𐑉air
Erər𐑼𐐲𐑉lover
ERɜːr𐑻𐐲𐑉hurt
iRɪər𐑽𐐮𐐲𐑉ear
yUjuː𐑿𐑏you

Consonants

None of the consonants require two keys.

Voiceless-voiced pairs

SequenceBEPAShavianDeseretExample
pp𐑐𐐹pat
bb𐑚𐐺bat
tt𐑑𐐻tie
dd𐑛𐐼deer
kk𐑒𐐿cat
gg𐑜𐑀get
ss𐑕𐑅sit
zz𐑟𐑆zip
ff𐑓𐑁fit
vv𐑝𐑂van
Tθ𐑔𐑃thank
Dð𐑞𐑄mother
Sʃ𐑖𐑇shell
Zʒ𐑠𐑈
Ctʃ𐑗𐐽chips
jdʒ𐑡𐐾juice
qtr𐑑𐑮𐐻𐑉try
Qdr𐑛𐑮𐐼𐑉dry
cts𐑑𐑕𐐻𐑅hats
Jdz𐑛𐑟𐐼𐑆hands

Aspirated, nasal and etc

SequenceBEPAShavianDeseretExample
hh𐑣𐐸hat
Hx𐑣𐐸loch
mm𐑥𐑋mad
nn𐑯𐑌nod
Nŋ𐑙𐑍ring
ll𐑤𐑊luck
rr𐑮𐑉ring
yj𐑘𐐷you
ww𐑢𐐶way

Specials

These characters will only be present in their respective alphabets, and will be null-routed in others.

SequenceBEPAShavianDeseretDescription
xˈN/AN/APrimary stress in BEPA/IPA.
XˌN/AN/ASecondary stress in BEPA/IPA.
ax ex ix ox uxN/A·N/ANaming dot in Shavian.

Key map

Some letters in traditional Mongolian may have multiple codepoints and mappings, this is reserved for different pronunciations of the identical-looking letters.

Vowels

| U+ | Keymap | IPA | Mongolian | Manchu | Sibe | Todo | | -- | -- | -- | -- | -- | -- | | 1820 | a | ɑ | ᠠ | ᠠ | ᠠ | ᠠ | | 1821 | e | ə | ᠡ | ᡝ | ᡝ | ᡄ | | 1822 | i | i | ᠢ | ᡳ | ᡞ | ᡅ | | 1823 | o | ɔ | ᠣ | ᠣ | ᠣ | ᡆ | | 1824 | u | ʊ | ᠤ | ᡡ | ᡡ | ᡇ | | 1825 | O | o | ᠥ | | | ᡈ | | 1826 | U | u | ᠦ | ᡠ | ᡠ | ᡉ | | 1827 | E | e | ᠧ | | | | | 185F | I | ɨ | | ᡟ | ᡟ | | | 1843 | `` | ː | | | | ᡃ |

Consonants

U+KeymapIPAMongolianManchuSibeTodo
1828nnᠨᠨᠨᠨ
1829Nŋᠩᠩᡢᡊ
182Abbᠪᠪᠪᡋ
182Bppᠫᡦᡦᡌ
182Chxᠬᡥᡥᡍ
182Dggᠭᡤᡤᡎ
182Emmᠮᠮᠮᡏ
182Fllᠯᠯᠯᠯ
1830ssá °á °á °á °
1831Sʃᠱᡧᡧᠱ
1832ttᠲᡩᡩᡐ
1833ddᠳᡨᡨᡑ
1834ctsᠴᠴᠴᡒ
1835jdzᠵᠵᡪᡓ
1836yjᠶᠶᠶᡕ
1837rrᠷᡵᠷᠷ
1838wwᠸᠸᠸᡖ
1839ffᠹᡶᡫᠸ
183Akkᠺᡴᡣᠺ
183CCt͡sᠼᡮᡮᡔ
183DJd͡zᠽᡯᡯᠴ
183Exxᠾᡙ
183Frhʐᠿᡰᡰ
1840lhɬᡀ
1841zhd͡ʐᡁᡷᡲ
1842cht͡ʂᡂᡱᡱ
1831shʂᠱᡧᡧ

Punctuations

U+KeymapMongolianManchuDescription
1801``᠁N/AEllipsis for Mongolian.
1802``᠂N/AComma for Mongolian.
1803``᠃N/AFull stop for Mongolian.
1804``᠄N/AColon for Mongolian.
1807``N/A᠇A bare tooth. "Glottal stop" letter; "Sibe syllable boundary marker" (SSBM).
1808``N/A᠈Comma for Manchu.
1809``N/A᠉Full stop for Manchu.
180A``᠊᠊Letter stem (Nirugu).
180B``᠋᠋Free variation selector 1.
180C``᠌᠌Free variation selector 2.
180D``᠍᠍Free variation selector 3.
180E``᠎N/ADisjoint tail in Mongolian.
180F``᠏᠏Free variation selector 4.
200C``‌‌Zero-width joiner (ZWJ).
200D``‍‍Zero-width joiner (ZWJ).
202F``  Narrow non-breaking space (NNBSP).

Rochelle

🔪 Stream chunk splitting.

Licensed under GNU LGPL 3.0. Named after Roach (Rochelle) in Cooking Roach and A Meal Fit for a King by Bucking Nonsense.

Modules

Text emitter

API

Static properties

  • SPLIT_UTF_8: Split by UTF-8. Also used by encodings like Shift JIS.
  • SPLIT_UTF_16LE: Split by UTF-16LE.
  • SPLIT_UTF_16BE: Split by UTF-16BE.

Constructor

new TextEmitter(stream: ReadableStream, splitMode: Number, label: String);
  • stream: The source stream of strings to read from.
  • splitMode: How to determine valid line feed (0x0a) and carriage return (0x0d) characters. Valid values are listed as SPLIT_* static properties.
  • label: One of the valid labels. Not implemented.

Events

chunk

MessageEvent<Uint8Array>

When a raw chunk is received from the stream.

close

Event

When the stream or the emitter closes.

error

ErrorEvent

When the emitter encounters a critical error.

fail

MessageEvent<Uint8Array>

When a line of text becomes available, but decoding failed. Returns the raw bytes.

raw

MessageEvent<Uint8Array>

When a line of text becomes available before decoding begins. Returns the raw bytes.

Raw line data will be flushed from buffer when the stream closes unexpectedly.

text

MessageEvent<String>

When a line of text becomes available. Returns the decoded line of text.

Properties

closed

Not implemented.

Boolean: TextEmitter.closed

If the text emitter is closed.

Methods

close()

Not implemented.

undefined: TextEmitter.close()

Close the current stream.

shx

📜 Bash/PDKSH shell action executor. A replacement for npx, deno task and etc.

All actions for shx should be written for Bash.

Supported shells

  • AT&T ksh93
    • Directory traversal does not work on ksh93 due to incorrect IFS behaviour.
    • Cannot be used as a runner.
  • Bash
  • Zsh

Usage

shx [<action> [<arguments>]]

Scripts will be run with Bash when present. If not, they'll be run with any supported shell.

Standard utilities

shx comes with a collection of QoL standard utilities.

  • amend: Update and amend the current commit, then push to remote.
  • build: A placeholder action for projects using shx to build themselves.
  • commit: Create a new commit, then push to remote.
  • echob: Printing bold text in the terminal.
  • push: A combination of shx build and shx commit.
  • release: Bundle build results into an archive. Configurable (upcoming).
  • sh: Spawn a Nix-powered shell with all development dependencies met.
  • tag: Tag the current commit, then push the tag to remote.
  • which: Fallback for environments not offering a which command.

Silk

Silk is an attempt to unify timelines of the MLP fandom on the Fediverse. It is achieved by merging all public timelines of instances with Mastodon-compatible APIs, and accounts that followed this account if on other instances. To avoid stressing tracked servers and accounts, WebSocket and SSE connections are utilized whenever possible, with caches enforced.

By bringing the MLP fandom on the Fediverse together, we attempt to make the Fediverse an appealing place for bronies and pegasisters alike, without any grip from a commercial entity. Find interesting people, discover content creators, anything is possible.

Don't know what Fediverse is? In laymen's terms, it's a cluster of inter-connected servers supporting a semi-decentralized social network. It has no single controlling entity, rendering takeover attempts happened to the blue bird impossible. But those are just words, why not join the Fediverse to experience it first-hoof?

Don't know which server to join? A list of servers is available here!

  • Inclusion: What's included in the timeline, and which server to join.
  • Moderation: How we moderate the merged timeline.
  • Usage: How to use Silk Web.
  • API: How to use Silk API.

Technical implementation

The list of servers to merge timelines can be customized, while moderation on specific users are implemented with existing Mastodon features. Accounts muted by the hook account are excluded from any self-service exemptions, while ones blocked by the hook account are excluded from the timeline altogether.

Hook accounts

The primary hook account is used for storing moderation information. Other instances usually do not need a hook account to be set up to read the local timeline.

Not every instance has its public timeline open to everyone though. As such, additional hook accounts are required on these instances.

Below is the list of hook accounts.

Open Source

Silk is a piece of open source software, licensed under GNU AGPL 3.0 or later.

If ready for public use, source code would be available on GitHub.

Content Inclusion

Instances

Silk will attempt to merge public timelines on all servers listed below.

Non-CW

The following instances have posts' content warning set as-is.

CW by default

Due to differences of the server rules, all of the following instances have posts' content warning enabled by default to comply the moderation rules.

Excluded instances

  • Pone.Social (https://pone.social) (removed due to incorrect configuration on the instance)

Requesting instance inclusion

We're open to include more instances to the list. If you host an instance which satisfies the following criteria, please contact us to have your instance included. We will assess before the final inclusion.

  • MLP-themed
  • Not a roleplay instance
  • Not supported by advertisement

Manual account inclusion

If your account isn't on any of the instances listed above, and said instance isn't mainly for the MLP community, you can follow the hook account to get yourself included manually. The hook account may also follow some accounts to have the same effect, mainly when said accounts do not have the ability to follow anyone (e.g. Equestria Daily).

Timeline Moderation

To grant as many members in the MLP community a pleasant experience as possible, we are enforcing a series of moderation rules on the merged timeline.

The rules are set on the basis of least intervention. They may change without prior notice, but we try our best to keep everyone notified.

Account exclusion

Accounts matching any criteria below will be excluded from the merged timeline altogether.

  • Nearly always advertise presence on other platforms without mingling on the Fediverse
  • Vent account
  • Promotion of self-harm
  • Promotion of hate speech, incl. racism, xenophobia, etc
  • Owner involved in harming of other individuals
  • Regularly not putting materials unsuitable for minors behind content warnings
  • Having no connection to the MLP fandom whatsoever

Instance auto-CW

Instances that permit accounts with the aforementioned criteria will get put behind content warnings by default.

Instance auto-CW exemption per-account

If you are on a server with content warning automatically enabled in the timeline, you can exempt yourself from the auto-CW status by following the hook account, as long as you follow the following rules. However, matching any criteria listed before will get your auto-CW exemption status revoked, or even entirely excluded.

Silk API

All APIs are assumed to be hosted at api.ltgc.cc if without further clarification.

Endpoints

GET /nr/silk/servers

Grab a list of included servers, along with their auto-CW status.

Returns an array of Server objects.

GET /nr/silk/timeline

Fetches a list of posts already stored on the server.

Returns an array of Post objects.

WS/SSE /rt/silk/timeline

If there are changes made to the timeline, this endpoint will push such changes to the clients.

Sents EventWrapper objects regardless of connection type.

Data structure

EventWrapper

{
	"event": <String>, // "set", "delete", "ack"
	"data": <Post|String|null>
}

Server

{
	"domain": "example.com",
	"cw": false,
	"active": true
}

Post

Except for Post.card and properties shown as null here, the data structure of Post objects have been pinned down.

Data of an example post is shown below.

{
	"id": "110464545243574580",
	"uri": "https://equestria.social/users/thatonegib/statuses/110464545243574580",
	"url": "https://equestria.social/@thatonegib/110464545243574580",
	"tags": [{
		"name": "mlp",
		"url": "https://equestria.social/tags/mlp"
	}],
	"emojis": [{
		"code": "flutteryay",
		"url": "https://equestria.social/system/custom_emojis/images/000/000/145/original/1295608.png",
		"static": "https://equestria.social/system/custom_emojis/images/000/000/145/static/1295608.png",
		"inPicker": true
	}, {
		"code": "ajsmug",
		"url": "https://equestria.social/system/custom_emojis/images/000/000/088/original/1292830.png",
		"static": "https://equestria.social/system/custom_emojis/images/000/000/088/static/1292830.png",
		"inPicker": true
	}],
	"card": null,
	"poll": {
		"id": "49940",
		"atExpire": 1685560245796,
		"expired": false,
		"multiple": false,
		"sumVote": 0,
		"sumVoter": 0,
		"options": [{
			"title": "Don't choose",
			"sumVote": 0
		},{
			"title": "Don't choose either",
			"sumVote": 0
		}],
		"emojis": []
	},
	"atNew": 1685555194757,
	"replyPost": "110464545243574580",
	"replyUser": "109524364471531266",
	"cwReal": false,
	"cwText": "",
	"access": "public",
	"lang": "en",
	"sumReply": 1,
	"sumBoost": 3,
	"sumFav": 3,
	"atEdit": 1685555194758,
	"text": "<p>Day 7: The Church. (final)</p>",
	"boost": null,
	"app": {
		"name": "Web",
		"site": "https://joinmastodon.org/"
	},
	"user": {
		"id": "109524364471531266",
		"username": "thatonegib",
		"acct": "thatonegib",
		"dispName": "Gib Riel-Delano",
		"locked": false,
		"bot": false,
		"discoverable": true,
		"group": false,
		"note": "<p>He/Him.<br />&quot;Road to hell is paved with good intentions&quot;<br />♥️ <br /><span class=\"h-card\"><a href=\"https://equestria.social/@AlzMarioWolfe\" class=\"u-url mention\">@<span>AlzMarioWolfe</span></a></span><br /> 💜 <br />@DamienInTheDark<br /> 04 Oct 2019<br />Comms CLOSED</p>",
		"url": "https://equestria.social/@thatonegib",
		"avatar": "https://equestria.social/system/accounts/avatars/109/524/364/471/531/266/original/8123b1c31f504128.jpg",
		"avatarStatic": "https://equestria.social/system/accounts/avatars/109/524/364/471/531/266/original/8123b1c31f504128.jpg",
		"header": "https://equestria.social/system/accounts/headers/109/524/364/471/531/266/original/e5cd38c16822e681.jpg",
		"headerStatic": "https://equestria.social/system/accounts/headers/109/524/364/471/531/266/original/e5cd38c16822e681.jpg",
		"sumPost": 58,
		"atLastPost": "2023-05-31",
		"noIndex": false,
		"emojis": [],
		"roles": [],
		"fields": [{
			"name": "Look through my Gallery!",
			"value": "<a href=\"https://www.deviantart.com/thatonegib/\" target=\"_blank\" rel=\"nofollow noopener noreferrer me\"><span class=\"invisible\">https://www.</span><span class=\"\">deviantart.com/thatonegib/</span><span class=\"invisible\"></span></a>",
			"atVerify": null
		}, {
			"name": "Help me make a living!",
			"value": "<a href=\"https://www.patreon.com/ThatOneGib\" target=\"_blank\" rel=\"nofollow noopener noreferrer me\"><span class=\"invisible\">https://www.</span><span class=\"\">patreon.com/ThatOneGib</span><span class=\"invisible\"></span></a>",
			"atVerify": null
		}, {
			"name": "Watch the sauce get made!",
			"value": "<a href=\"https://www.youtube.com/channel/UC2V6hQau5NkH4abuBFoFhyg\" target=\"_blank\" rel=\"nofollow noopener noreferrer me\"><span class=\"invisible\">https://www.</span><span class=\"ellipsis\">youtube.com/channel/UC2V6hQau5</span><span class=\"invisible\">NkH4abuBFoFhyg</span></a>",
			"atVerify": null
		}, {
			"name": "Obligatory Twatter link",
			"value": "<a href=\"https://twitter.com/ThatOneGib\" target=\"_blank\" rel=\"nofollow noopener noreferrer me\"><span class=\"invisible\">https://</span><span class=\"\">twitter.com/ThatOneGib</span><span class=\"invisible\"></span></a>",
			"atVerify": null
		}],
		"atNew": 1671148800000,
		"sumFan": 25,
		"sumSub": 5
	},
	"media": [{
		"id": "110464545127306536",
		"type": "image",
		"url": "https://equestria.social/system/media_attachments/files/110/464/545/127/306/536/original/4f8c3b035aede9ea.jpeg",
		"preview": "https://equestria.social/system/media_attachments/files/110/464/545/127/306/536/small/4f8c3b035aede9ea.jpeg",
		"remote": null,
		"previewRemote": null,
		"text": null,
		"meta": {
			"original": {
				"width": 1015,
				"height": 2042,
				"size": "1015x2042",
				"aspect": 0.4970617042115573
			},
			"small":{
				"width": 338,
				"height": 680,
				"size": "338x680",
				"aspect": 0.4970588235294118
			}
		},
		"alt": "Alt text example",
		"blurhash": "USAAX:WFMtogouocMyWBjXa$f,jZIUWBxukC"
	}],
	"ats": [{
		"id": "110377043343501824",
		"username": "silk",
		"url": "https://equestria.social/@silk",
		"acct": "silk"
	}],
	"handle": "@[email protected]",
	"rid": "[email protected]"
}

Service Usage

For ease of use, Silk provides an API and a web frontend.

API

Please refer to API.

Web frontend

The web frontend is expected to become publicly available at mlp.ltgc.cc.

If you have internal access, you might also be able to try it out at staging.ltgc.cc (NXDOMAIN expected).

Snowy

A BroadcastChannel polyfill for Firefox 29+ and Chromium 5+, implemented with SharedWorker.

Snowy will not be active if BroadcastChannel already exists.

Usage

  • Place snowy.js under the root directory of your website.
    • If snowy.js needs to be placed somewhere else, set self.SNOWY_PATH to where snowy.js resides.
  • Run bc.js in your page to start the polyfill.

SynPix

👾 The open pixel font for embedded LCDs.

SynPix is a union effort of GFHK-SDGM, PoneyClairDeLune and JayB.

Support

Unicode Blocks

  • ASCII
  • Latin-9
  • Some additional Latin alphabets, see below for details
  • IPA (U+0250 - U+029F, upcoming in version 0.3)
  • U+02C6 - U+02CF
  • Monotonic Greek (lacking some bare diacritics)
  • Cyrillic (only Russian, Ukrainian and pre-1918 Russian currently, see below for upcoming updates)
  • Armenian (upcoming in version 0.3)
  • Hebrew (basic letters only, no full Yiddish support yet)
  • Georgian (upcoming in version 0.3)
  • Cherokee (upcoming)
  • Runes (upcoming in version 0.3)
  • Tai Le (upcoming in version 0.3)
  • New Tai Lüe (upcoming)
  • Roman numerals (U+2160 - U+2165)
  • Bagua symbols (upcoming in version 0.3)
  • Astronomical symbols (upcoming in version 0.3)
  • Zodiac symbols
  • Coptic (upcoming in version 0.3)
  • CJK radicals supplement (partial complete)
  • Kangxi radicals (except 9 characters “⼢⼮⿋⿎⿏⿐⿒⿔⿕”)
  • CJK symbols and punctuation (、。々〇「」)
  • “Hangzhou” numerals
  • Hiragana (missing 3 characters “ぎぱぽ”)
  • Katakana (missing 5 characters “パヷヸヹヺ”)
  • Bopomofo
  • Hangul compatibility jamo (done for modern jamos)
  • CJKV Ideographs (see below for details)
  • Lisu (Fraser alphabet) (upcoming in version 0.3)
  • Phags-pa (upcoming)
  • Full-width ASCII (upcoming in version 0.3)
  • Half-width katakana
  • Half-width Hangul
  • Various currency symbols (partial complete, ¢£¥€¢£¥)
  • Gothic (upcoming?)

EU Official Languages

  • Bulgarian (done in basic Cyrillics)
  • Croatian (upcoming in version 0.3, no tone marks yet)
  • Czech (upcoming in version 0.3)
  • Danish (done in Latin-9, except Ǿǿ, which is done in 0.3)
  • Dutch (done in Latin-9, except digraph IJij, which is done in 0.3)
  • English (done in ASCII)
  • Estonian (done in Latin-9)
  • Finnish (done in Latin-9)
  • French (done in Latin-9)
  • German (done in Latin-9, except uppercase ẞ, which is done in 0.3)
  • Greek (currently monotonic only)
  • Hungarian (upcoming)
  • Irish (done in Latin-9 for modern orthography, old orthography upcoming)
  • Italian (done in Latin-9)
  • Latvian (upcoming in version 0.3)
  • Lithuanian (upcoming in version 0.3)
  • Maltese (upcoming in version 0.3)
  • Polish (upcoming in version 0.3)
  • Portuguese (done in Latin-9)
  • Romanian (upcoming in version 0.3)
  • Slovak (upcoming in version 0.3)
  • Slovene (upcoming in version 0.3, no tone marks yet)
  • Spanish (done in Latin-9)
  • Swedish (done in Latin-9)

Latin Alphabets

For the official languages of the European Union, refer to the list above.

  • Serbo – Croatian (Latin) (upcoming in version 0.3)
  • Esperanto (upcoming in version 0.3)

Romanization Systems

  • Hànyǔ PÄ«nyÄ«n

Cyrillic Alphabets

  • Russian
  • Ukrainian (Ґґ Єє Іі Її)
  • Pre-1918 Russian (four extra letters: Іі Ѣѣ Ѳѳ Ѵѵ)
  • Bulgarian
  • Belarusian (Іі, Ўў, upcoming in version 0.3)
  • Serbo – Croatian (Cyrillic) (Ђђ Јј Љљ Њњ Ћћ Џџ, upcoming in version 0.3, no tone marks yet)
  • Macedonian (Ѓѓ Ѐѐ Ѕѕ Ѝѝ Јј Љљ Њњ Ќќ Џџ, upcoming in version 0.3)
  • Mongolian (Cyrillic) (Ó¨Ó© Ò®Ò¯, upcoming in version 0.3)
  • Kazakh (Cyrillic) (Әә Ғғ Ққ Ò¢Ò£ Ó¨Ó© Ò°Ò± Ò®Ò¯ ÒºÒ» Іі, upcoming in version 0.3)
  • Uzbek (Cyrillic) (Ўў Ққ Ғғ Ò²Ò³, upcoming in version 0.3)
  • Kyrgyz (Ò¢Ò£ Ó¨Ó© Ò®Ò¯, upcoming in version 0.3)
  • Tajik (Ғғ Ó¢Ó£ Ққ Ó®Ó¯ Ò²Ò³ Ò¶Ò·, upcoming in version 0.3)

CJKV Ideographs

As of version 2023m27a, we currently have about 516 (?) unrepeated glyphs, 606 if counted the repeated ones.

㘯一丁七万丈三上下不丐丑丙丨个丫
中丰丶丸丹主丽丿乃久么义之乙九乞
也习乡书亅了予二于亏云互五井亜亞
亠亡亢亥京人亿什仁仃今介仑仓代令
以任会伝伟何你來侖修倉個偉傳億儿
兀兄兆光克党入八六兰共关其典冂円
冖冫冬几凡凵出刀刁刃力加劳労勇勝
勞勹勺匕北匚匸区區十千午华南卜卝
卤卩卯厂原厡厶去县又叉友发口可台
史司合向吕君吾呂告命和問善営囗囚
四回圆圓土在地场坂基堀場塲士壬声
夂处复夏夕多夜大天女威子孑孓存学
學宀它安宏官宝实実宠室宫宮家寅實
寵寶寸小少尔尢尸尹尼尽尾屮山川工
己已巳巴巷巾布帜幟干平年幸幺广広
庆库庚庫廠廣廴廾廿弋弓弥彌彐彡彥
彦彳復心志忘思恩恭恵悅惠慶戈戊戌
成我戶户戸所手才支攴攵政文斉斗斤
方施无日早时春昭昼時晝智暢曜曰書
會月木未本朱村来松某栄梁梅森榮欠
止正歹殳毅毋母比毛氏民气氣水汉污
河治沼沿法洽流浩海淸清港漢火点無
營爪父爻爾爿片牙牛犬玄玉王瓜瓦甘
生用田由甲申画畅畫疋疒癶癸發白百
皇皮皿盡目直県眞真矛矢知石示祭禸
禾私秋穴空立童竹範籐米糸紀細維網
縣纪细维缶网羊美羔義羽習翠老而耒
耳聲聿肉胜臣自至臺臼舌舛舟艮色艸
艹花草荣菊華营萬藤蘭虍處虧虫蟲血
行衣複襾西覆見见角言詩語論謠謡識
论识语谷豆豊豐豕豸貝贝赤走越足身
車転轉车转辛辰辱辵达过近送透造過
道達邑邓郷鄉鄕鄧酉酒釆里重金長长
門関闗關门问阜阳阴降陰陽隆隶隹雄
難雨雪靑青非面革韋韦韭音頁須页须
風风飛飞食首香馬馱駄马驮骨高髟鬥
鬯鬲鬼魔魚鯉鱼鲤鳥鸟鹵鹿麗麥麦麻
黃黄黍黑黒點黨黽黾鼎齊齐龍龙

Track me, senpai!

Exploiting reverse psychology to convince people switch to privacy-friendly browsers. Uses a combination of server-side detection and cookie storage.

Usage

Just deploy the page and the appropriate detection method.

Server-side detection

Server-side detection should not breach any privacy law, as the visitor is already supplying every possible information to the server.

Caddy

header Accept-CH "sec-ch-ua-full-version,ua-full-version,sec-ch-ua-full-version-list"
@chromeVictims {
	header "Sec-CH-UA-Full-Version-List" *Chrom*
	not header "Cookie" *track-me-senpai*
	not path /track-me/*
}
@otherVictims {
	header "Sec-CH-UA" `*"Google Chrome"*`
	header "Sec-CH-UA" `*"Microsoft Edge"*`
	header "Sec-CH-UA" `*"Edge"*`
	header "Sec-CH-UA" `*"Opera"*`
	header "Sec-CH-UA" `*Arc*`
	not header "Cookie" *track-me-senpai*
	not path /track-me/*
}
redir @chromeVictims "/track-me/?src={uri}"
redir @otherVictims "/track-me/?src={uri}"

Client-side detection

Client-side detection may breach privacy laws. It will be developed if requested.

WingBlade

WingBlade is an abstraction layer targeting multiple JavaScript runtimes simultaneously. No TypeScript support is considered.

Projects utilizing WingBlade are expected to write web-oriented platform-agnostic code. For the most part, unless a better measure is found, WingBlade adheres to the Deno API scheme.

API

Open Source

Silk is a piece of open source software, licensed under GNU LGPL 3.0 or later.

Source code is available on the following code hosting services.

System

WingBlade.rt.cores

Use

Report the amount of CPU cores.

Syntax

Number: WingBlade.rt.cores

WingBlade.rt.exit

Use

Exit the current runtime with given status code. 0 by default.

Syntax

undefined: WingBlade.rt.exit(Number: code = 0);

WingBlade.rt.memory

Use

Report memory usage of the current runtime. All values are in bytes.

Syntax

MemoryUsage: WingBlade.rt.memory
{
	external: Number, // Memory associated with JS objects outside of the JS isolate.
	free: Number, // The size of available RAM.
	heapTotal: Number, // The total size of the heap of the JS engine.
	heapUsed: Number, // The size of the heap used by the JS engine.
	rss: Number, // Resident Set Size, aka memory occupied in RAM.
	total: Number // The total size of the RAM.
}

WingBlade.rt.networkDefer

Use

Indicate whether or not the current runtime is only allowed network access during triggering.

Useful for serverless functions.

Syntax

Boolean: WingBlade.rt.networkDefer

WingBlade.rt.os

Use

Report the current operating system. Examples include windows, darwin and linux.

Syntax

String: WingBlade.rt.os

WingBlade.rt.persist

Use

Indicate whether or not the current runtime executes persistent sessions. If reports false, the runtime will only be activated upon triggering, and will be destroyed when the triggered tasks finish.

Useful for serverless functions.

Syntax

Boolean: WingBlade.rt.persist

WingBlade.rt.variant

Use

Report the name of the current runtime WingBlade runs on. Examples include Node, Deno and Bun.

Syntax

String: WingBlade.rt.variant

WingBlade.rt.version

Use

Report the version of the current runtime WingBlade runs on.

Syntax

String: WingBlade.rt.version

Environment variables

Note

WingBlade.env can also be used as a normal JavaScript Object.

WingBlade.env.get

Use

Return an environment variable, and supply a fallback value if given.

Syntax

?String: WingBlade.env.get(String: key, ?String: fallbackValue);

WingBlade.env.set

Use

Set an environment variable with given value.

Syntax

undefined: WingBlade.env.set(String: key, String: value);

WingBlade.env.delete

Use

Remove an environment variable.

Syntax

undefined: WingBlade.env.delete(String: key);

WingBlade.env.has

Use

Indicate whether or not an environment variable exists.

Syntax

Boolean: WingBlade.env.has(String: key);

WingBlade.env.toObject

Use

Return a snapshot of all current environment variables as an Object.

Syntax

Object: WingBlade.env.toObject();

Filesystem

WingBlade.file.read()

Use

Read the whole file as Uint8Array.

Syntax

Promise<Uint8Array>: WingBlade.file.read(String: path, Object<ReadFileOptions>: opt);

Read Deno.ReadFileOptions for the opt params.

WingBlade.file.write()

Use

Write the whole Uint8Array as a file.

Syntax

Promise<undefined>: WingBlade.file.write(String: path, Uint8Array: data, Object<WriteFileOptions>: opt);

Read Deno.WriteFileOptions for the opt params.

Utilities

WingBlade.util.randomInt

Use

Return a random integer between 0 (inclusive) and a value given (exclusive).

Syntax

Number: WingBlade.util.randomInt(Number: cap);

WingBlade.util.sleep

Use

Sleep for a given amount of time (in milliseconds).

Syntax

Promise<undefined>: WingBlade.util.sleep(Number: ms, ?Number: maxAdd = 0);

Networking

Web services

WingBlade.web.serve

Use

Start a web server with a handler function.

Syntax

WebServer: WingBlade.web.serve(AsyncFunction<Response>: handler, ?ServeInit: opt = {});

Read ServeInit@std/http/server for more details.

handler

let handler = async function (Request: request, ConnInfo: connInfo) {
	return new Response();
};

WingBlade.web.acceptWs

Use

Upgrade the incoming request to a WebSocket connection.

Syntax

UpgradedWebSocket: WingBlade.web.acceptWs(Request: req, UpgradeWebSocketOptions: opt);

UpgradedWebSocket

{
	response: Response, // The upgrade response for the client
	socket: WebSocketServer // Server-side WebSocket
}

UpgradeWebSocketOptions

{
	protocol: String,
	idleTimeout: Number
}

Read Deno.UpgradeWebSocketOptions for details.

WingBlade.web.acceptSSE

Use

Upgrade the incoming request to a Server-sent Event (EventSink) connection.

Syntax

UpgradedSSE: WingBlade.web.acceptSSE(Request: req);

UpgradedSSE

{
	response: Response, // The upgrade response to the client
	socket: EventSink // Server-side EventSource
}

Web Stream

Quick ReadableStream convertion

Warning

If the stream exploits the same ArrayBuffer to emit chunks, at least on Deno, all of the readings will error out.

The Deno implementation may take twice as much RAM usage as on other runtimes.

ReadableStream.prototype.array()

ReadableStream.prototype.arrayBuffer()

ReadableStream.prototype.blob()

ReadableStream.prototype.json()

ReadableStream.prototype.text()

Stream behaviour modification

ChokerStream

Use

Apply chunk-size normalization to the attached stream.

The chunk first gets written to the normalized buffer, and if the buffer exceeds the target chunk size, a normalized chunk will get emitted. If the attached stream closes, all remaining data in the buffer will also be emitted.

Syntax

let object = new ChokerStream(Number: maxChunkSize = 1024, Boolean: alwaysCopy = false);
ChokerStream {
	alwaysCopy: Boolean, // Read-only. Disables zero-copy when available if set to true.
	chunk: Number, // A positive integer defining the normalized chunk size.
	source: ReadableStream, // Get the choked readable stream.
	sink: ReadableStream, // Read-only. The attached readable stream source.
	attach: function () {} // Attach to a readable stream source.
}