@standardserver/core
Advanced tools
+12
-2
@@ -77,3 +77,3 @@ interface EventMeta { | ||
| type StandardMethod = 'GET' | 'POST' | 'PUT' | 'DELETE' | 'PATCH' | 'OPTIONS' | 'HEAD' | (string & {}); | ||
| type StandardMethod = 'GET' | 'POST' | 'PUT' | 'DELETE' | 'PATCH' | 'OPTIONS' | 'HEAD' | 'QUERY' | (string & {}); | ||
| type StandardUrl = `/${string}` | `/${string}?${string}` | `/${string}#${string}` | `/${string}?${string}#${string}`; | ||
@@ -147,2 +147,12 @@ interface StandardHeaders { | ||
| declare function flattenStandardHeader(header: string | readonly string[] | undefined): string | undefined; | ||
| /** | ||
| * Resolves how a receiver parses a body from the standard headers alone, | ||
| * mirroring what the body parsers do. | ||
| */ | ||
| declare function resolveStandardBodyHint(headers: { | ||
| 'standard-server'?: undefined | string | string[]; | ||
| 'content-type'?: undefined | string | string[]; | ||
| 'content-length'?: undefined | string | string[]; | ||
| 'content-disposition'?: undefined | string | string[]; | ||
| }): StandardBodyHint; | ||
| declare function mergeStandardHeaders(a: StandardHeaders, b: StandardHeaders): StandardHeaders; | ||
@@ -162,3 +172,3 @@ declare function parseStandardUrl(url: StandardUrl): [ | ||
| export { ErrorEvent, EventStreamDecoder, EventStreamDecoderError, EventStreamDecoderStream, EventStreamEncoderError, assertEventStreamMessageComment, assertEventStreamMessageId, assertEventStreamMessageName, assertEventStreamMessageRetry, decodeEventStreamMessage, encodeEventStreamMessage, encodeEventStreamMessageComments, encodeEventStreamMessageData, flattenStandardHeader, generateContentDisposition, getEventMeta, getFilenameFromContentDisposition, isStandardHeaders, isStandardMethod, isStandardRequest, isStandardResponse, isStandardStatus, isStandardUrl, mergeStandardHeaders, parseStandardUrl, unwrapEvent, withEventMeta }; | ||
| export { ErrorEvent, EventStreamDecoder, EventStreamDecoderError, EventStreamDecoderStream, EventStreamEncoderError, assertEventStreamMessageComment, assertEventStreamMessageId, assertEventStreamMessageName, assertEventStreamMessageRetry, decodeEventStreamMessage, encodeEventStreamMessage, encodeEventStreamMessageComments, encodeEventStreamMessageData, flattenStandardHeader, generateContentDisposition, getEventMeta, getFilenameFromContentDisposition, isStandardHeaders, isStandardMethod, isStandardRequest, isStandardResponse, isStandardStatus, isStandardUrl, mergeStandardHeaders, parseStandardUrl, resolveStandardBodyHint, unwrapEvent, withEventMeta }; | ||
| export type { ErrorEventOptions, EventMeta, EventStreamMessage, StandardBody, StandardBodyHint, StandardHeaders, StandardLazyRequest, StandardLazyResponse, StandardMethod, StandardRequest, StandardResponse, StandardUrl }; |
+12
-2
@@ -77,3 +77,3 @@ interface EventMeta { | ||
| type StandardMethod = 'GET' | 'POST' | 'PUT' | 'DELETE' | 'PATCH' | 'OPTIONS' | 'HEAD' | (string & {}); | ||
| type StandardMethod = 'GET' | 'POST' | 'PUT' | 'DELETE' | 'PATCH' | 'OPTIONS' | 'HEAD' | 'QUERY' | (string & {}); | ||
| type StandardUrl = `/${string}` | `/${string}?${string}` | `/${string}#${string}` | `/${string}?${string}#${string}`; | ||
@@ -147,2 +147,12 @@ interface StandardHeaders { | ||
| declare function flattenStandardHeader(header: string | readonly string[] | undefined): string | undefined; | ||
| /** | ||
| * Resolves how a receiver parses a body from the standard headers alone, | ||
| * mirroring what the body parsers do. | ||
| */ | ||
| declare function resolveStandardBodyHint(headers: { | ||
| 'standard-server'?: undefined | string | string[]; | ||
| 'content-type'?: undefined | string | string[]; | ||
| 'content-length'?: undefined | string | string[]; | ||
| 'content-disposition'?: undefined | string | string[]; | ||
| }): StandardBodyHint; | ||
| declare function mergeStandardHeaders(a: StandardHeaders, b: StandardHeaders): StandardHeaders; | ||
@@ -162,3 +172,3 @@ declare function parseStandardUrl(url: StandardUrl): [ | ||
| export { ErrorEvent, EventStreamDecoder, EventStreamDecoderError, EventStreamDecoderStream, EventStreamEncoderError, assertEventStreamMessageComment, assertEventStreamMessageId, assertEventStreamMessageName, assertEventStreamMessageRetry, decodeEventStreamMessage, encodeEventStreamMessage, encodeEventStreamMessageComments, encodeEventStreamMessageData, flattenStandardHeader, generateContentDisposition, getEventMeta, getFilenameFromContentDisposition, isStandardHeaders, isStandardMethod, isStandardRequest, isStandardResponse, isStandardStatus, isStandardUrl, mergeStandardHeaders, parseStandardUrl, unwrapEvent, withEventMeta }; | ||
| export { ErrorEvent, EventStreamDecoder, EventStreamDecoderError, EventStreamDecoderStream, EventStreamEncoderError, assertEventStreamMessageComment, assertEventStreamMessageId, assertEventStreamMessageName, assertEventStreamMessageRetry, decodeEventStreamMessage, encodeEventStreamMessage, encodeEventStreamMessageComments, encodeEventStreamMessageData, flattenStandardHeader, generateContentDisposition, getEventMeta, getFilenameFromContentDisposition, isStandardHeaders, isStandardMethod, isStandardRequest, isStandardResponse, isStandardStatus, isStandardUrl, mergeStandardHeaders, parseStandardUrl, resolveStandardBodyHint, unwrapEvent, withEventMeta }; | ||
| export type { ErrorEventOptions, EventMeta, EventStreamMessage, StandardBody, StandardBodyHint, StandardHeaders, StandardLazyRequest, StandardLazyResponse, StandardMethod, StandardRequest, StandardResponse, StandardUrl }; |
+39
-1
@@ -276,2 +276,40 @@ import { isTypescriptObject, getOrBind, tryDecodeURIComponent, toArray } from '@standardserver/shared'; | ||
| } | ||
| const STANDARD_BODY_HINT_SET = /* @__PURE__ */ new Set([ | ||
| "json", | ||
| "form-data", | ||
| "url-search-params", | ||
| "event-stream", | ||
| "octet-stream", | ||
| "file", | ||
| "none" | ||
| ]); | ||
| function resolveStandardBodyHint(headers) { | ||
| const hint = flattenStandardHeader(headers["standard-server"]); | ||
| if (hint !== void 0 && STANDARD_BODY_HINT_SET.has(hint)) { | ||
| return hint; | ||
| } | ||
| const mimeType = flattenStandardHeader(headers["content-type"])?.split(";")[0]?.trim().toLowerCase(); | ||
| const contentLength = flattenStandardHeader(headers["content-length"]); | ||
| const contentDisposition = flattenStandardHeader(headers["content-disposition"]); | ||
| const fileName = contentDisposition !== void 0 ? getFilenameFromContentDisposition(contentDisposition) : void 0; | ||
| if (mimeType === void 0 && (contentLength === void 0 || contentLength === "0")) { | ||
| return "none"; | ||
| } | ||
| if (mimeType === "application/json") { | ||
| return "json"; | ||
| } | ||
| if (mimeType === "multipart/form-data") { | ||
| return "form-data"; | ||
| } | ||
| if (mimeType === "application/x-www-form-urlencoded") { | ||
| return "url-search-params"; | ||
| } | ||
| if (mimeType === "text/event-stream") { | ||
| return "event-stream"; | ||
| } | ||
| if (fileName !== void 0 || contentLength !== void 0) { | ||
| return "file"; | ||
| } | ||
| return "octet-stream"; | ||
| } | ||
| function mergeStandardHeaders(a, b) { | ||
@@ -337,2 +375,2 @@ const merged = { ...a, ...b }; | ||
| export { ErrorEvent, EventStreamDecoder, EventStreamDecoderError, EventStreamDecoderStream, EventStreamEncoderError, assertEventStreamMessageComment, assertEventStreamMessageId, assertEventStreamMessageName, assertEventStreamMessageRetry, decodeEventStreamMessage, encodeEventStreamMessage, encodeEventStreamMessageComments, encodeEventStreamMessageData, flattenStandardHeader, generateContentDisposition, getEventMeta, getFilenameFromContentDisposition, isStandardHeaders, isStandardMethod, isStandardRequest, isStandardResponse, isStandardStatus, isStandardUrl, mergeStandardHeaders, parseStandardUrl, unwrapEvent, withEventMeta }; | ||
| export { ErrorEvent, EventStreamDecoder, EventStreamDecoderError, EventStreamDecoderStream, EventStreamEncoderError, assertEventStreamMessageComment, assertEventStreamMessageId, assertEventStreamMessageName, assertEventStreamMessageRetry, decodeEventStreamMessage, encodeEventStreamMessage, encodeEventStreamMessageComments, encodeEventStreamMessageData, flattenStandardHeader, generateContentDisposition, getEventMeta, getFilenameFromContentDisposition, isStandardHeaders, isStandardMethod, isStandardRequest, isStandardResponse, isStandardStatus, isStandardUrl, mergeStandardHeaders, parseStandardUrl, resolveStandardBodyHint, unwrapEvent, withEventMeta }; |
+2
-2
| { | ||
| "name": "@standardserver/core", | ||
| "type": "module", | ||
| "version": "0.7.1", | ||
| "version": "0.8.0", | ||
| "license": "MIT", | ||
@@ -25,3 +25,3 @@ "homepage": "https://standardserver.dev", | ||
| "dependencies": { | ||
| "@standardserver/shared": "0.7.1" | ||
| "@standardserver/shared": "0.8.0" | ||
| }, | ||
@@ -28,0 +28,0 @@ "scripts": { |
+226
-99
@@ -1,2 +0,2 @@ | ||
| # @standardserver/core | ||
| # Standard Server | ||
@@ -24,17 +24,21 @@ <div align="center"> | ||
| `@standardserver/core` is the shared contract package for Standard Server. | ||
| `@standardserver/core` is the shared contract package for **Standard Server** — a unified interface for client-server communication across HTTP and message-based transports. It lets you keep handler and client code transport-agnostic by working with the same request, response, body, and streaming abstractions whether the transport is Fetch, Node.js HTTP, or a peer-style message channel. | ||
| Standard Server provides a unified interface for client-server communication across HTTP and message-based transports. It lets you keep handler and client code transport-agnostic by working with the same request, response, body, and streaming abstractions whether the transport is Fetch, Node.js HTTP, or a peer-style message channel. | ||
| Standard Server ships as a small ecosystem of packages: | ||
| This package is the foundation of that model. It defines the core request and response types, shared runtime validators, small utility helpers, and event stream (SSE) helpers. | ||
| | Package | Description | | ||
| | ------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------- | | ||
| | [`@standardserver/core`](https://github.com/middleapi/standardserver/blob/main/packages/core/README.md) | The shared contract: types, body parsing rules, validators, and SSE helpers | | ||
| | [`@standardserver/fetch`](https://github.com/middleapi/standardserver/blob/main/packages/fetch/README.md) | Fetch API adapter for browsers, workers, and other Fetch-based runtimes | | ||
| | [`@standardserver/node`](https://github.com/middleapi/standardserver/blob/main/packages/node/README.md) | Node.js HTTP and HTTP/2 adapter | | ||
| | [`@standardserver/fastify`](https://github.com/middleapi/standardserver/blob/main/packages/fastify/README.md) | Fastify adapter built on the Node.js adapter | | ||
| | [`@standardserver/aws-lambda`](https://github.com/middleapi/standardserver/blob/main/packages/aws-lambda/README.md) | AWS Lambda adapter with response streaming | | ||
| | [`@standardserver/peer`](https://github.com/middleapi/standardserver/blob/main/packages/peer/README.md) | Message-based adapter for WebSocket, MessagePort, and custom transports | | ||
| | [`@standardserver/shared`](https://github.com/middleapi/standardserver/blob/main/packages/shared/README.md) | Internal utilities shared across the ecosystem | | ||
| ## Entry Points | ||
| This package is the foundation of that model. It defines the request and response types every adapter converts to and from, the body parsing rules they all share, runtime validators, header and URL utilities, and event stream (SSE) helpers. | ||
| | Entry point | Purpose | | ||
| | ---------------------- | -------------------------------------------------------- | | ||
| | `@standardserver/core` | Shared request/response types, utilities, and validators | | ||
| ## Request and response types | ||
| The main entry point exposes four transport-agnostic shapes: | ||
| The package exposes four transport-agnostic shapes: | ||
@@ -79,3 +83,3 @@ | Export | Description | | ||
| ### Body hints and body values | ||
| ## Body types | ||
@@ -90,18 +94,144 @@ `StandardBodyHint` and `StandardBody` describe the shared body contract used across adapters: | ||
| | `event-stream` | `AsyncIteratorObject<unknown>` | `text/event-stream` | Server-Sent Events (SSE) | | ||
| | `octet-stream` | `ReadableStream<Uint8Array>` | any | Binary payloads | | ||
| | `octet-stream` | `ReadableStream<Uint8Array>` | any | Binary streaming | | ||
| | `file` | `File` | any | Fixed-size binary payloads for both `File` and `Blob` | | ||
| | `none` | `undefined` | | Empty body | | ||
| ### Resolving Body | ||
| ### JSON body | ||
| `resolveBody(hint?)` determines how to parse the body using the following priority: | ||
| Standard Server treats primitive values, objects, and arrays as JSON. | ||
| 1. If `hint?` is provided, use it as the `StandardBodyHint`. | ||
| 2. Otherwise, if the `standard-server` header is present, use it as the `StandardBodyHint`. | ||
| 3. Otherwise, if `content-type` is one of the common types, parse accordingly. | ||
| 4. Otherwise, if `content-length` exists, treat the body as `file`; if not, treat it as `octet-stream`. | ||
| ```ts | ||
| import type { StandardRequest } from '@standardserver/core' | ||
| For efficient communication, set the `standard-server` header to explicitly hint the body type, especially for file or binary streaming. For example, if you upload a file with a common `content-type` such as `application/json` but omit the `standard-server` header, the server may interpret it as JSON and parse it unexpectedly. | ||
| const request: StandardRequest = { | ||
| method: 'POST', | ||
| url: '/submit', | ||
| headers: {}, | ||
| body: { name: 'John Doe', email: 'john.doe@example.com' }, | ||
| } | ||
| ``` | ||
| ### FormData and URLSearchParams body | ||
| Standard Server treats [FormData](https://developer.mozilla.org/en-US/docs/Web/API/FormData) and [URLSearchParams](https://developer.mozilla.org/en-US/docs/Web/API/URLSearchParams) as form submissions. | ||
| ```ts | ||
| import type { StandardRequest } from '@standardserver/core' | ||
| const requestWithURLSearchParams: StandardRequest = { | ||
| method: 'POST', | ||
| url: '/submit', | ||
| headers: {}, | ||
| body: new URLSearchParams({ name: 'John Doe', email: 'john.doe@example.com' }), | ||
| } | ||
| const formData = new FormData() | ||
| formData.append('name', 'John Doe') | ||
| formData.append('file', new Blob(['Hello, World!'], { type: 'text/plain' }), 'hello.txt') | ||
| const requestWithFormData: StandardRequest = { | ||
| method: 'POST', | ||
| url: '/submit', | ||
| headers: {}, | ||
| body: formData, | ||
| } | ||
| ``` | ||
| > [!TIP] | ||
| > HTML forms submit data as `application/x-www-form-urlencoded` or `multipart/form-data`, so these body types are especially helpful there. | ||
| ### File and Blob body | ||
| Standard Server treats [File](https://developer.mozilla.org/en-US/docs/Web/API/File) and [Blob](https://developer.mozilla.org/en-US/docs/Web/API/Blob) as fixed-size binary payloads. | ||
| > [!NOTE] | ||
| > Since `File` extends `Blob`, `resolveBody` always returns a `File` when representing either `File` or `Blob` bodies. | ||
| ```ts | ||
| import type { StandardResponse } from '@standardserver/core' | ||
| const response: StandardResponse = { | ||
| status: 200, | ||
| headers: { | ||
| 'content-disposition': [], // <- remove auto-set header | ||
| }, | ||
| body: new File(['Hello, World!'], 'hello.txt', { type: 'text/plain' }), | ||
| } | ||
| ``` | ||
| When sending a file or blob body, adapters automatically set the `content-length`, `content-type`, `content-disposition`, and `standard-server` headers based on the provided body. You can override any of them by explicitly providing a header value, or remove one entirely by assigning an empty array. | ||
| ### Event-stream body | ||
| Standard Server uses [AsyncIteratorObject](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/AsyncIterator) to represent an event stream body, and you can use `withEventMeta()` to attach additional [SSE event metadata](https://developer.mozilla.org/en-US/docs/Web/API/Server-sent_events/Using_server-sent_events#event_stream_format) to each emitted event. | ||
| ```ts | ||
| import type { StandardResponse } from '@standardserver/core' | ||
| import { ErrorEvent, withEventMeta } from '@standardserver/core' | ||
| const response: StandardResponse = { | ||
| status: 200, | ||
| headers: {}, | ||
| async* body() { | ||
| yield withEventMeta( | ||
| { message: 'Hello, World!' }, | ||
| { id: '1', retry: 3000, comments: ['hidden'] }, | ||
| ) | ||
| throw new ErrorEvent({ message: 'Something went wrong' }) | ||
| return { message: 'This is the end of the stream' } | ||
| }, | ||
| } | ||
| ``` | ||
| Events are interpreted as follows: `yield` emits a `message`, `throw` emits an `error`, and `return` emits a `close` event. Note that `close` does not cause [EventSource](https://developer.mozilla.org/en-US/docs/Web/API/EventSource) to close the connection because it is not part of the SSE specification. However, when using Standard Server for client-side streaming, `close` is treated as the end of the stream, so the connection is closed and no reconnection is attempted. | ||
| For explicit SSE encoding, decoding, and metadata handling, see the [Event-Stream Helpers](#event-stream-helpers) below. | ||
| ### Octet-stream body | ||
| Standard Server uses [ReadableStream<Uint8Array>](https://developer.mozilla.org/en-US/docs/Web/API/ReadableStream) to represent a binary streaming body. | ||
| ```ts | ||
| import type { StandardResponse } from '@standardserver/core' | ||
| const response: StandardResponse = { | ||
| status: 200, | ||
| headers: { | ||
| 'content-type': 'application/octet-stream', | ||
| }, | ||
| body: new ReadableStream<Uint8Array>({ | ||
| start(controller) { | ||
| const encoder = new TextEncoder() | ||
| controller.enqueue(encoder.encode('Hello, World!')) | ||
| controller.close() | ||
| }, | ||
| }), | ||
| } | ||
| ``` | ||
| When sending a binary streaming body, adapters automatically set the `content-type` and `standard-server` headers. You can override `content-type` by providing an explicit header value, or remove it entirely by assigning an empty array. | ||
| ## How body parsing works | ||
| > [!NOTE] | ||
| > This section applies to the HTTP adapters (Fetch, Node.js, Fastify, AWS Lambda). It does not apply to the [peer adapter](https://github.com/middleapi/standardserver/blob/main/packages/peer/README.md#body-resolution), which identifies body types through its own message protocol — a different but fairly similar mechanism. | ||
| `resolveBody(hint?)` on `StandardLazyRequest` and `StandardLazyResponse` resolves the body lazily — the underlying stream is only consumed once you call it. The `StandardBodyHint` that decides how the raw body is parsed comes from three places: an explicit `hint` argument, the `standard-server` header, or inference from the content headers. | ||
| ### The `standard-server` header | ||
| A `StandardBody` is richer than what HTTP content headers can describe. `content-type` tells the receiver the _media type_ of the bytes, but not which `StandardBody` representation the sender intended: | ||
| - A file upload can legitimately carry `content-type: application/json`. Without more information, the receiver would parse it into a JSON value when the sender meant a `File` to be stored as-is. | ||
| - A fixed-size binary payload (`file`) and a binary stream (`octet-stream`) can share any content type. Telling them apart otherwise depends on `content-length`, which proxies may rewrite and some runtimes drop when the payload is empty. | ||
| The `standard-server` header closes this gap. It carries the sender's `StandardBodyHint` verbatim — `json`, `form-data`, `url-search-params`, `event-stream`, `octet-stream`, `file`, or `none` — so the receiver reconstructs exactly the body representation the sender had. | ||
| Adapters set the header automatically for the ambiguous body types: a `Blob` or `File` body is sent with `standard-server: file`, and a `ReadableStream` body with `standard-server: octet-stream`, alongside the usual content headers. A header you set yourself always wins, and assigning an empty array removes it entirely. For the other body types, the content headers are enough, so adapters clear it. | ||
| The header is optional: when it is absent or invalid, the receiver falls back to content-header inference, so plain HTTP clients work as-is. Just set the header yourself whenever the content type alone could be misread: | ||
| ```ts | ||
| const response = await fetch('/upload', { | ||
@@ -111,3 +241,3 @@ method: 'POST', | ||
| 'content-type': 'application/json', | ||
| 'standard-server': 'file', // <- hint the body type to avoid misinterpretation | ||
| 'standard-server': 'file', // <- keep the payload a File on the server | ||
| }, | ||
@@ -118,5 +248,37 @@ body: new Blob(['{"message": "Hello, world!"}'], { type: 'application/json' }), | ||
| ### Resolution order | ||
| The hint is chosen in this order: | ||
| 1. **Explicit `hint` argument.** If you pass a hint to `resolveBody(hint)`, it always wins. | ||
| 2. **The `standard-server` header.** If present and holding a valid hint value, it is used verbatim. Unknown values are ignored. | ||
| 3. **Content-header inference:** | ||
| 1. No `content-type`, and `content-length` absent or `0` → `none`. | ||
| 2. A common `content-type` → `application/json` parses as `json`, `multipart/form-data` as `form-data`, `application/x-www-form-urlencoded` as `url-search-params`, and `text/event-stream` as `event-stream`. Media type casing and parameters such as `; charset=utf-8` are ignored. | ||
| 3. A `content-disposition` carrying a filename, or any `content-length` → `file`. | ||
| 4. Anything else → `octet-stream`. | ||
| This resolution is implemented once in this package as `resolveStandardBodyHint(headers)` and shared by every HTTP adapter, so the same body parses the same way regardless of which HTTP transport carried it: | ||
| ```ts | ||
| import { resolveStandardBodyHint } from '@standardserver/core' | ||
| resolveStandardBodyHint({ 'content-type': 'application/json' }) | ||
| // 'json' | ||
| resolveStandardBodyHint({ | ||
| 'content-type': 'application/json', | ||
| 'standard-server': 'file', | ||
| }) | ||
| // 'file' | ||
| resolveStandardBodyHint({}) | ||
| // 'none' | ||
| ``` | ||
| Use it when building a custom adapter, or when you need to know how a body will parse without consuming it. | ||
| ## Utilities | ||
| The main entry point also exports a small set of helpers for common header and URL operations. | ||
| The package also exports a small set of helpers for common header and URL operations. | ||
@@ -209,3 +371,3 @@ ### Content-Disposition helpers | ||
| The event-stream entry point exposes: | ||
| The event-stream helpers include: | ||
@@ -285,3 +447,3 @@ - `EventMeta` for `id`, `retry`, and `comments` | ||
| The subpath also exports: | ||
| The package also exports: | ||
@@ -310,3 +472,3 @@ - `EventStreamEncoderError` for invalid outbound SSE messages | ||
| For the higher-level project overview, see the root [Standard Server README](../../README.md). | ||
| For transport-specific quick-starts and options, see the adapter documentation: [Fetch](https://github.com/middleapi/standardserver/blob/main/packages/fetch/README.md) · [Node.js](https://github.com/middleapi/standardserver/blob/main/packages/node/README.md) · [Fastify](https://github.com/middleapi/standardserver/blob/main/packages/fastify/README.md) · [AWS Lambda](https://github.com/middleapi/standardserver/blob/main/packages/aws-lambda/README.md) · [Peer](https://github.com/middleapi/standardserver/blob/main/packages/peer/README.md) | ||
@@ -321,3 +483,3 @@ ## Sponsors | ||
| <tr> | ||
| <td align="center"><a href="https://screenshotone.com/?ref=orpc" target="_blank" rel="noopener" title="ScreenshotOne.com"><img src="https://avatars.githubusercontent.com/u/97035603?v=4" width="279" alt="ScreenshotOne.com"/><br />ScreenshotOne.com</a></td> | ||
| <td align="center"><a href="https://screenshotone.com/?ref=orpc" target="_blank" rel="sponsored noopener" title="ScreenshotOne.com"><img src="https://avatars.githubusercontent.com/u/97035603?v=4" width="279" alt="ScreenshotOne.com"/><br />ScreenshotOne.com</a></td> | ||
| </tr> | ||
@@ -330,3 +492,3 @@ </table> | ||
| <tr> | ||
| <td align="center"><a href="https://misskey.io/?ref=orpc" target="_blank" rel="noopener" title="村上さん"><img src="https://avatars.githubusercontent.com/u/37681609?u=0dd4c7e4ba937cbb52b068c55914b1d8164dc0c7&v=4" width="209" alt="村上さん"/><br />村上さん</a></td> | ||
| <td align="center"><a href="https://misskey.io/?ref=orpc" target="_blank" rel="sponsored noopener" title="村上さん"><img src="https://avatars.githubusercontent.com/u/37681609?u=0dd4c7e4ba937cbb52b068c55914b1d8164dc0c7&v=4" width="209" alt="村上さん"/><br />村上さん</a></td> | ||
| </tr> | ||
@@ -339,3 +501,3 @@ </table> | ||
| <tr> | ||
| <td align="center"><a href="https://github.com/ln-markets?ref=orpc" target="_blank" rel="noopener" title="LN Markets"><img src="https://avatars.githubusercontent.com/u/70597625?v=4" width="167" alt="LN Markets"/><br />LN Markets</a></td> | ||
| <td align="center"><a href="https://github.com/ln-markets?ref=orpc" target="_blank" rel="sponsored noopener" title="LN Markets"><img src="https://avatars.githubusercontent.com/u/70597625?v=4" width="167" alt="LN Markets"/><br />LN Markets</a></td> | ||
| </tr> | ||
@@ -348,20 +510,22 @@ </table> | ||
| <tr> | ||
| <td align="center"><a href="https://github.com/hrmcdonald?ref=orpc" target="_blank" rel="noopener" title="Reece McDonald"><img src="https://avatars.githubusercontent.com/u/39349270?v=4" width="139" alt="Reece McDonald"/><br />Reece McDonald</a></td> | ||
| <td align="center"><a href="https://github.com/nicognaW?ref=orpc" target="_blank" rel="noopener" title="nk"><img src="https://avatars.githubusercontent.com/u/66731869?u=4699bda3a9092d3ec34fbd959450767bcc8b8b6d&v=4" width="139" alt="nk"/><br />nk</a></td> | ||
| <td align="center"><a href="https://github.com/supastarter?ref=orpc" target="_blank" rel="noopener" title="supastarter"><img src="https://avatars.githubusercontent.com/u/110960143?v=4" width="139" alt="supastarter"/><br />supastarter</a></td> | ||
| <td align="center"><a href="https://github.com/divmgl?ref=orpc" target="_blank" rel="noopener" title="Dexter Miguel"><img src="https://avatars.githubusercontent.com/u/5452298?u=645993204be8696c085ecf0d228c3062efe2ed65&v=4" width="139" alt="Dexter Miguel"/><br />Dexter Miguel</a></td> | ||
| <td align="center"><a href="https://github.com/herrfugbaum?ref=orpc" target="_blank" rel="noopener" title="herrfugbaum"><img src="https://avatars.githubusercontent.com/u/12859776?u=644dc1666d0220bc0468eb0de3c56b919f635b16&v=4" width="139" alt="herrfugbaum"/><br />herrfugbaum</a></td> | ||
| <td align="center"><a href="https://github.com/ryota-murakami?ref=orpc" target="_blank" rel="noopener" title="Ryota Murakami"><img src="https://avatars.githubusercontent.com/u/5501268?u=599389e03340734325726ca3f8f423c021d47d7f&v=4" width="139" alt="Ryota Murakami"/><br />Ryota Murakami</a></td> | ||
| <td align="center"><a href="https://github.com/hrmcdonald?ref=orpc" target="_blank" rel="sponsored noopener" title="Reece McDonald"><img src="https://avatars.githubusercontent.com/u/39349270?v=4" width="139" alt="Reece McDonald"/><br />Reece McDonald</a></td> | ||
| <td align="center"><a href="https://github.com/u1-liquid?ref=orpc" target="_blank" rel="sponsored noopener" title="あわわわとーにゅ"><img src="https://avatars.githubusercontent.com/u/17376330?u=de3353804be889f009f7e0a1582daf04d0ab292d&v=4" width="139" alt="あわわわとーにゅ"/><br />あわわわとーにゅ</a></td> | ||
| <td align="center"><a href="https://github.com/nicognaW?ref=orpc" target="_blank" rel="sponsored noopener" title="nk"><img src="https://avatars.githubusercontent.com/u/66731869?u=4699bda3a9092d3ec34fbd959450767bcc8b8b6d&v=4" width="139" alt="nk"/><br />nk</a></td> | ||
| <td align="center"><a href="https://github.com/supastarter?ref=orpc" target="_blank" rel="sponsored noopener" title="supastarter"><img src="https://avatars.githubusercontent.com/u/110960143?v=4" width="139" alt="supastarter"/><br />supastarter</a></td> | ||
| <td align="center"><a href="https://github.com/divmgl?ref=orpc" target="_blank" rel="sponsored noopener" title="Dexter Miguel"><img src="https://avatars.githubusercontent.com/u/5452298?u=645993204be8696c085ecf0d228c3062efe2ed65&v=4" width="139" alt="Dexter Miguel"/><br />Dexter Miguel</a></td> | ||
| <td align="center"><a href="https://github.com/herrfugbaum?ref=orpc" target="_blank" rel="sponsored noopener" title="herrfugbaum"><img src="https://avatars.githubusercontent.com/u/12859776?u=644dc1666d0220bc0468eb0de3c56b919f635b16&v=4" width="139" alt="herrfugbaum"/><br />herrfugbaum</a></td> | ||
| </tr> | ||
| <tr> | ||
| <td align="center"><a href="https://github.com/dcramer?ref=orpc" target="_blank" rel="noopener" title="David Cramer"><img src="https://avatars.githubusercontent.com/u/23610?v=4" width="139" alt="David Cramer"/><br />David Cramer</a></td> | ||
| <td align="center"><a href="https://github.com/valerii15298?ref=orpc" target="_blank" rel="noopener" title="Valerii Petryniak"><img src="https://avatars.githubusercontent.com/u/44531564?u=88ac74d9bacd20401518441907acad21063cd397&v=4" width="139" alt="Valerii Petryniak"/><br />Valerii Petryniak</a></td> | ||
| <td align="center"><a href="https://github.com/letstri?ref=orpc" target="_blank" rel="noopener" title="Valerii Strilets"><img src="https://avatars.githubusercontent.com/u/13253748?u=c7b10399ccc8f8081e24db94ec32cd9858e86ac3&v=4" width="139" alt="Valerii Strilets"/><br />Valerii Strilets</a></td> | ||
| <td align="center"><a href="https://github.com/K-Mistele?ref=orpc" target="_blank" rel="noopener" title="Kyle Mistele"><img src="https://avatars.githubusercontent.com/u/18430555?u=3afebeb81de666e35aaac3ed46f14159d7603ffb&v=4" width="139" alt="Kyle Mistele"/><br />Kyle Mistele</a></td> | ||
| <td align="center"><a href="https://github.com/christ12938?ref=orpc" target="_blank" rel="noopener" title="christ12938"><img src="https://avatars.githubusercontent.com/u/25758598?v=4" width="139" alt="christ12938"/><br />christ12938</a></td> | ||
| <td align="center"><a href="https://github.com/Ryanjso?ref=orpc" target="_blank" rel="noopener" title="Ryan Soderberg"><img src="https://avatars.githubusercontent.com/u/39172778?u=5ed913c31d57e7221b75784abcad48c7ebddde27&v=4" width="139" alt="Ryan Soderberg"/><br />Ryan Soderberg</a></td> | ||
| <td align="center"><a href="https://github.com/ryota-murakami?ref=orpc" target="_blank" rel="sponsored noopener" title="Ryota Murakami"><img src="https://avatars.githubusercontent.com/u/5501268?u=599389e03340734325726ca3f8f423c021d47d7f&v=4" width="139" alt="Ryota Murakami"/><br />Ryota Murakami</a></td> | ||
| <td align="center"><a href="https://github.com/dcramer?ref=orpc" target="_blank" rel="sponsored noopener" title="David Cramer"><img src="https://avatars.githubusercontent.com/u/23610?v=4" width="139" alt="David Cramer"/><br />David Cramer</a></td> | ||
| <td align="center"><a href="https://github.com/valerii15298?ref=orpc" target="_blank" rel="sponsored noopener" title="Valerii Petryniak"><img src="https://avatars.githubusercontent.com/u/44531564?u=88ac74d9bacd20401518441907acad21063cd397&v=4" width="139" alt="Valerii Petryniak"/><br />Valerii Petryniak</a></td> | ||
| <td align="center"><a href="https://github.com/letstri?ref=orpc" target="_blank" rel="sponsored noopener" title="Valerii Strilets"><img src="https://avatars.githubusercontent.com/u/13253748?u=c7b10399ccc8f8081e24db94ec32cd9858e86ac3&v=4" width="139" alt="Valerii Strilets"/><br />Valerii Strilets</a></td> | ||
| <td align="center"><a href="https://github.com/K-Mistele?ref=orpc" target="_blank" rel="sponsored noopener" title="Kyle Mistele"><img src="https://avatars.githubusercontent.com/u/18430555?u=3afebeb81de666e35aaac3ed46f14159d7603ffb&v=4" width="139" alt="Kyle Mistele"/><br />Kyle Mistele</a></td> | ||
| <td align="center"><a href="https://github.com/christ12938?ref=orpc" target="_blank" rel="sponsored noopener" title="christ12938"><img src="https://avatars.githubusercontent.com/u/25758598?v=4" width="139" alt="christ12938"/><br />christ12938</a></td> | ||
| </tr> | ||
| <tr> | ||
| <td align="center"><a href="https://github.com/itigoore01?ref=orpc" target="_blank" rel="noopener" title="shota"><img src="https://avatars.githubusercontent.com/u/11831107?u=c976a6dc7e055eb026304c46c99100ed22b0c8e0&v=4" width="139" alt="shota"/><br />shota</a></td> | ||
| <td align="center"><a href="https://github.com/ellis-driscoll?ref=orpc" target="_blank" rel="noopener" title="Ellis Driscoll"><img src="https://avatars.githubusercontent.com/u/70685966?u=c5f95bc33b5991d9744abe00052542e4a2ed3cb9&v=4" width="139" alt="Ellis Driscoll"/><br />Ellis Driscoll</a></td> | ||
| <td align="center"><a href="https://github.com/Ryanjso?ref=orpc" target="_blank" rel="sponsored noopener" title="Ryan Soderberg"><img src="https://avatars.githubusercontent.com/u/39172778?u=5ed913c31d57e7221b75784abcad48c7ebddde27&v=4" width="139" alt="Ryan Soderberg"/><br />Ryan Soderberg</a></td> | ||
| <td align="center"><a href="https://github.com/itigoore01?ref=orpc" target="_blank" rel="sponsored noopener" title="shota"><img src="https://avatars.githubusercontent.com/u/11831107?u=c976a6dc7e055eb026304c46c99100ed22b0c8e0&v=4" width="139" alt="shota"/><br />shota</a></td> | ||
| <td align="center"><a href="https://github.com/ellis-driscoll?ref=orpc" target="_blank" rel="sponsored noopener" title="Ellis Driscoll"><img src="https://avatars.githubusercontent.com/u/70685966?u=c5f95bc33b5991d9744abe00052542e4a2ed3cb9&v=4" width="139" alt="Ellis Driscoll"/><br />Ellis Driscoll</a></td> | ||
| <td align="center"><a href="https://github.com/hoangbn?ref=orpc" target="_blank" rel="sponsored noopener" title="Hoang Nguyen"><img src="https://avatars.githubusercontent.com/u/38968280?u=c90084c6de65c56facabab7ba13a72a49ddbc3e4&v=4" width="139" alt="Hoang Nguyen"/><br />Hoang Nguyen</a></td> | ||
| </tr> | ||
@@ -374,67 +538,30 @@ </table> | ||
| <tr> | ||
| <td align="center"><a href="https://github.com/rhinodavid?ref=orpc" target="_blank" rel="noopener" title="David Walsh"><img src="https://avatars.githubusercontent.com/u/5778036?u=b5521f07d2f88c3db2a0dae62b5f2f8357214af0&v=4" width="119" alt="David Walsh"/><br />David Walsh</a></td> | ||
| <td align="center"><a href="https://github.com/Robbe95?ref=orpc" target="_blank" rel="noopener" title="Robbe Vaes"><img src="https://avatars.githubusercontent.com/u/44748019?u=e0232402c045ad4eac7cbd217f1f47e083103b89&v=4" width="119" alt="Robbe Vaes"/><br />Robbe Vaes</a></td> | ||
| <td align="center"><a href="https://github.com/aidansunbury?ref=orpc" target="_blank" rel="noopener" title="Aidan Sunbury"><img src="https://avatars.githubusercontent.com/u/64103161?v=4" width="119" alt="Aidan Sunbury"/><br />Aidan Sunbury</a></td> | ||
| <td align="center"><a href="https://github.com/soonoo?ref=orpc" target="_blank" rel="noopener" title="soonoo"><img src="https://avatars.githubusercontent.com/u/5436405?u=5d0b4aa955c87e30e6bda7f0cccae5402da99528&v=4" width="119" alt="soonoo"/><br />soonoo</a></td> | ||
| <td align="center"><a href="https://github.com/kporten?ref=orpc" target="_blank" rel="noopener" title="Kevin Porten"><img src="https://avatars.githubusercontent.com/u/1839345?u=dc2263d5cfe0d927ce1a0be04a1d55dd6b55405c&v=4" width="119" alt="Kevin Porten"/><br />Kevin Porten</a></td> | ||
| <td align="center"><a href="https://github.com/pumpkinlink?ref=orpc" target="_blank" rel="noopener" title="Denis"><img src="https://avatars.githubusercontent.com/u/11864620?u=5f47bbe6c65d0f6f5cf011021490238e4b0593d0&v=4" width="119" alt="Denis"/><br />Denis</a></td> | ||
| <td align="center"><a href="https://github.com/christopher-kapic?ref=orpc" target="_blank" rel="noopener" title="Christopher Kapic"><img src="https://avatars.githubusercontent.com/u/59740769?u=e7ad4b72b5bf6c9eb1644c26dbf3332a8f987377&v=4" width="119" alt="Christopher Kapic"/><br />Christopher Kapic</a></td> | ||
| <td align="center"><a href="https://github.com/rhinodavid?ref=orpc" target="_blank" rel="sponsored noopener" title="David Walsh"><img src="https://avatars.githubusercontent.com/u/5778036?u=b5521f07d2f88c3db2a0dae62b5f2f8357214af0&v=4" width="119" alt="David Walsh"/><br />David Walsh</a></td> | ||
| <td align="center"><a href="https://github.com/Robbe95?ref=orpc" target="_blank" rel="sponsored noopener" title="Robbe Vaes"><img src="https://avatars.githubusercontent.com/u/44748019?u=e0232402c045ad4eac7cbd217f1f47e083103b89&v=4" width="119" alt="Robbe Vaes"/><br />Robbe Vaes</a></td> | ||
| <td align="center"><a href="https://github.com/aidansunbury?ref=orpc" target="_blank" rel="sponsored noopener" title="Aidan Sunbury"><img src="https://avatars.githubusercontent.com/u/64103161?v=4" width="119" alt="Aidan Sunbury"/><br />Aidan Sunbury</a></td> | ||
| <td align="center"><a href="https://github.com/soonoo?ref=orpc" target="_blank" rel="sponsored noopener" title="soonoo"><img src="https://avatars.githubusercontent.com/u/5436405?u=5d0b4aa955c87e30e6bda7f0cccae5402da99528&v=4" width="119" alt="soonoo"/><br />soonoo</a></td> | ||
| <td align="center"><a href="https://github.com/kporten?ref=orpc" target="_blank" rel="sponsored noopener" title="Kevin Porten"><img src="https://avatars.githubusercontent.com/u/1839345?u=dc2263d5cfe0d927ce1a0be04a1d55dd6b55405c&v=4" width="119" alt="Kevin Porten"/><br />Kevin Porten</a></td> | ||
| <td align="center"><a href="https://github.com/pumpkinlink?ref=orpc" target="_blank" rel="sponsored noopener" title="Denis"><img src="https://avatars.githubusercontent.com/u/11864620?u=5f47bbe6c65d0f6f5cf011021490238e4b0593d0&v=4" width="119" alt="Denis"/><br />Denis</a></td> | ||
| <td align="center"><a href="https://github.com/christopher-kapic?ref=orpc" target="_blank" rel="sponsored noopener" title="Christopher Kapic"><img src="https://avatars.githubusercontent.com/u/59740769?u=e7ad4b72b5bf6c9eb1644c26dbf3332a8f987377&v=4" width="119" alt="Christopher Kapic"/><br />Christopher Kapic</a></td> | ||
| </tr> | ||
| <tr> | ||
| <td align="center"><a href="https://github.com/thomasballinger?ref=orpc" target="_blank" rel="noopener" title="Tom Ballinger"><img src="https://avatars.githubusercontent.com/u/458879?u=4b045ac75d721b6ac2b42a74d7d37f61f0414031&v=4" width="119" alt="Tom Ballinger"/><br />Tom Ballinger</a></td> | ||
| <td align="center"><a href="https://github.com/SSam0419?ref=orpc" target="_blank" rel="noopener" title="Sam"><img src="https://avatars.githubusercontent.com/u/102863520?u=3c89611f549d5070be232eb4532f690c8f2e7a65&v=4" width="119" alt="Sam"/><br />Sam</a></td> | ||
| <td align="center"><a href="https://github.com/Titoine?ref=orpc" target="_blank" rel="noopener" title="Titoine"><img src="https://avatars.githubusercontent.com/u/3514286?u=1bb1e86b0c99c8a1121372e56d51a177eea12191&v=4" width="119" alt="Titoine"/><br />Titoine</a></td> | ||
| <td align="center"><a href="https://github.com/Mnigos?ref=orpc" target="_blank" rel="noopener" title="Igor Makowski"><img src="https://avatars.githubusercontent.com/u/56691628?u=ee8c879478f7c151b9156aef6c74243fa3e247a8&v=4" width="119" alt="Igor Makowski"/><br />Igor Makowski</a></td> | ||
| <td align="center"><a href="https://github.com/hanayashiki?ref=orpc" target="_blank" rel="noopener" title="hanayashiki"><img src="https://avatars.githubusercontent.com/u/26056783?u=06c3b9205a16fd41a871e82da1cc2a09306d53f5&v=4" width="119" alt="hanayashiki"/><br />hanayashiki</a></td> | ||
| <td align="center"><a href="https://github.com/ldub?ref=orpc" target="_blank" rel="noopener" title="Lev Dubinets"><img src="https://avatars.githubusercontent.com/u/3114081?u=f547f5d5012cab54851f1b1ad72d10e537f78fc2&v=4" width="119" alt="Lev Dubinets"/><br />Lev Dubinets</a></td> | ||
| <td align="center"><a href="https://github.com/mr-kelly?ref=orpc" target="_blank" rel="noopener" title="Kelly Peilin Chan"><img src="https://avatars.githubusercontent.com/u/520852?u=6b0f7105f694e7b5cacf410a3f04c7044b469dc8&v=4" width="119" alt="Kelly Peilin Chan"/><br />Kelly Peilin Chan</a></td> | ||
| <td align="center"><a href="https://github.com/thomasballinger?ref=orpc" target="_blank" rel="sponsored noopener" title="Tom Ballinger"><img src="https://avatars.githubusercontent.com/u/458879?u=4b045ac75d721b6ac2b42a74d7d37f61f0414031&v=4" width="119" alt="Tom Ballinger"/><br />Tom Ballinger</a></td> | ||
| <td align="center"><a href="https://github.com/SSam0419?ref=orpc" target="_blank" rel="sponsored noopener" title="Sam"><img src="https://avatars.githubusercontent.com/u/102863520?u=3c89611f549d5070be232eb4532f690c8f2e7a65&v=4" width="119" alt="Sam"/><br />Sam</a></td> | ||
| <td align="center"><a href="https://github.com/Titoine?ref=orpc" target="_blank" rel="sponsored noopener" title="Titoine"><img src="https://avatars.githubusercontent.com/u/3514286?u=1bb1e86b0c99c8a1121372e56d51a177eea12191&v=4" width="119" alt="Titoine"/><br />Titoine</a></td> | ||
| <td align="center"><a href="https://github.com/Mnigos?ref=orpc" target="_blank" rel="sponsored noopener" title="Igor Makowski"><img src="https://avatars.githubusercontent.com/u/56691628?u=ee8c879478f7c151b9156aef6c74243fa3e247a8&v=4" width="119" alt="Igor Makowski"/><br />Igor Makowski</a></td> | ||
| <td align="center"><a href="https://github.com/hanayashiki?ref=orpc" target="_blank" rel="sponsored noopener" title="hanayashiki"><img src="https://avatars.githubusercontent.com/u/26056783?u=06c3b9205a16fd41a871e82da1cc2a09306d53f5&v=4" width="119" alt="hanayashiki"/><br />hanayashiki</a></td> | ||
| <td align="center"><a href="https://github.com/ldub?ref=orpc" target="_blank" rel="sponsored noopener" title="Lev Dubinets"><img src="https://avatars.githubusercontent.com/u/3114081?u=f547f5d5012cab54851f1b1ad72d10e537f78fc2&v=4" width="119" alt="Lev Dubinets"/><br />Lev Dubinets</a></td> | ||
| <td align="center"><a href="https://github.com/mr-kelly?ref=orpc" target="_blank" rel="sponsored noopener" title="Kelly Peilin Chan"><img src="https://avatars.githubusercontent.com/u/520852?u=6b0f7105f694e7b5cacf410a3f04c7044b469dc8&v=4" width="119" alt="Kelly Peilin Chan"/><br />Kelly Peilin Chan</a></td> | ||
| </tr> | ||
| <tr> | ||
| <td align="center"><a href="https://github.com/guyariely?ref=orpc" target="_blank" rel="noopener" title="Guy Ariely"><img src="https://avatars.githubusercontent.com/u/42813496?u=edb6b7f563bf28e160a290832e7da57c0506f8ca&v=4" width="119" alt="Guy Ariely"/><br />Guy Ariely</a></td> | ||
| <td align="center"><a href="https://github.com/piscis?ref=orpc" target="_blank" rel="noopener" title="Alex"><img src="https://avatars.githubusercontent.com/u/326163?u=b245f368bd940cf51d08c0b6bf55f8257f359437&v=4" width="119" alt="Alex"/><br />Alex</a></td> | ||
| <td align="center"><a href="https://github.com/finom?ref=orpc" target="_blank" rel="noopener" title="Andrey Gubanov"><img src="https://avatars.githubusercontent.com/u/1082083?u=c5f2daf7ebece498e85c83367bb37b4e10e2649d&v=4" width="119" alt="Andrey Gubanov"/><br />Andrey Gubanov</a></td> | ||
| <td align="center"><a href="https://github.com/guyariely?ref=orpc" target="_blank" rel="sponsored noopener" title="Guy Ariely"><img src="https://avatars.githubusercontent.com/u/42813496?u=edb6b7f563bf28e160a290832e7da57c0506f8ca&v=4" width="119" alt="Guy Ariely"/><br />Guy Ariely</a></td> | ||
| <td align="center"><a href="https://github.com/piscis?ref=orpc" target="_blank" rel="sponsored noopener" title="Alex"><img src="https://avatars.githubusercontent.com/u/326163?u=b245f368bd940cf51d08c0b6bf55f8257f359437&v=4" width="119" alt="Alex"/><br />Alex</a></td> | ||
| <td align="center"><a href="https://github.com/finom?ref=orpc" target="_blank" rel="sponsored noopener" title="Andrey Gubanov"><img src="https://avatars.githubusercontent.com/u/1082083?u=c5f2daf7ebece498e85c83367bb37b4e10e2649d&v=4" width="119" alt="Andrey Gubanov"/><br />Andrey Gubanov</a></td> | ||
| </tr> | ||
| </table> | ||
| ### Past Sponsors | ||
| With thanks to 37 past sponsors who helped get us here. | ||
| <p> | ||
| <a href="https://github.com/MrMaxie?ref=orpc" target="_blank" rel="noopener" title="Maxie"><img src="https://avatars.githubusercontent.com/u/3857836?u=5e6b57973d4385d655663ffdd836e487856f2984&v=4" width="32" height="32" alt="Maxie" /></a> | ||
| <a href="https://github.com/Stijn-Timmer?ref=orpc" target="_blank" rel="noopener" title="Stijn Timmer"><img src="https://avatars.githubusercontent.com/u/100147665?u=106b2c18e9c98a61861b4ee7fc100f5b9906a6c9&v=4" width="32" height="32" alt="Stijn Timmer" /></a> | ||
| <a href="https://github.com/u1-liquid?ref=orpc" target="_blank" rel="noopener" title="あわわわとーにゅ"><img src="https://avatars.githubusercontent.com/u/17376330?u=de3353804be889f009f7e0a1582daf04d0ab292d&v=4" width="32" height="32" alt="あわわわとーにゅ" /></a> | ||
| <a href="https://github.com/zuplo?ref=orpc" target="_blank" rel="noopener" title="Zuplo"><img src="https://avatars.githubusercontent.com/u/85497839?v=4" width="32" height="32" alt="Zuplo" /></a> | ||
| <a href="https://github.com/motopods?ref=orpc" target="_blank" rel="noopener" title="motopods"><img src="https://avatars.githubusercontent.com/u/58200641?v=4" width="32" height="32" alt="motopods" /></a> | ||
| <a href="https://github.com/franciscohermida?ref=orpc" target="_blank" rel="noopener" title="Francisco Hermida"><img src="https://avatars.githubusercontent.com/u/483242?u=bbcbc80eb9d8781ff401f7dafc3b59cd7bea0561&v=4" width="32" height="32" alt="Francisco Hermida" /></a> | ||
| <a href="https://github.com/theoludwig?ref=orpc" target="_blank" rel="noopener" title="Théo LUDWIG"><img src="https://avatars.githubusercontent.com/u/25207499?u=a6a9653725a2f574c07893748806668e0598cdbe&v=4" width="32" height="32" alt="Théo LUDWIG" /></a> | ||
| <a href="https://github.com/abhay-ramesh?ref=orpc" target="_blank" rel="noopener" title="Abhay Ramesh"><img src="https://avatars.githubusercontent.com/u/66196314?u=c5c2b0327b26606c2efcfaf17046ab18c3d25c57&v=4" width="32" height="32" alt="Abhay Ramesh" /></a> | ||
| <a href="https://github.com/shr-ink?ref=orpc" target="_blank" rel="noopener" title="shr.ink oü"><img src="https://avatars.githubusercontent.com/u/139700438?v=4" width="32" height="32" alt="shr.ink oü" /></a> | ||
| <a href="https://github.com/johngerome?ref=orpc" target="_blank" rel="noopener" title="0x4e32"><img src="https://avatars.githubusercontent.com/u/2002000?u=505e54608466ab53754f702973687b04c6424c1f&v=4" width="32" height="32" alt="0x4e32" /></a> | ||
| <a href="https://github.com/yzuyr?ref=orpc" target="_blank" rel="noopener" title="Ryuz"><img src="https://avatars.githubusercontent.com/u/196539378?u=d38374588d219b6748b16406982f6559411466d4&v=4" width="32" height="32" alt="Ryuz" /></a> | ||
| <a href="https://github.com/happyboy2022?ref=orpc" target="_blank" rel="noopener" title="happyboy"><img src="https://avatars.githubusercontent.com/u/103669586?u=65b49c4b893ed3703909fbb3a7a22313f3f9c121&v=4" width="32" height="32" alt="happyboy" /></a> | ||
| <a href="https://github.com/YiCChi?ref=orpc" target="_blank" rel="noopener" title="yicchi"><img src="https://avatars.githubusercontent.com/u/86967274?u=6c2756f09fe15dd94d572f560e979cd157982852&v=4" width="32" height="32" alt="yicchi" /></a> | ||
| <a href="https://github.com/cloudycotton?ref=orpc" target="_blank" rel="noopener" title="Saksham"><img src="https://avatars.githubusercontent.com/u/168998965?u=9b9634a5aed66a51c1b880663272725b00b92b14&v=4" width="32" height="32" alt="Saksham" /></a> | ||
| <a href="https://github.com/hrynevychroman?ref=orpc" target="_blank" rel="noopener" title="Roman Hrynevych"><img src="https://avatars.githubusercontent.com/u/82209198?u=1a1d111ab3d589855b9cc8a7fefb1b5c6a4fbbaf&v=4" width="32" height="32" alt="Roman Hrynevych" /></a> | ||
| <a href="https://github.com/rokitgg?ref=orpc" target="_blank" rel="noopener" title="rokitg"><img src="https://avatars.githubusercontent.com/u/125133357?u=06c74aefaa2236b06a2e5fba5a5c612339f45912&v=4" width="32" height="32" alt="rokitg" /></a> | ||
| <a href="https://github.com/omarkhatibgg?ref=orpc" target="_blank" rel="noopener" title="Omar Khatib"><img src="https://avatars.githubusercontent.com/u/9054278?u=afbba7331b85c51b8eee4130f5fd31b1017dc919&v=4" width="32" height="32" alt="Omar Khatib" /></a> | ||
| <a href="https://github.com/YuSabo90002?ref=orpc" target="_blank" rel="noopener" title="Yu-Sabo"><img src="https://avatars.githubusercontent.com/u/13120582?v=4" width="32" height="32" alt="Yu-Sabo" /></a> | ||
| <a href="https://github.com/bapspatil?ref=orpc" target="_blank" rel="noopener" title="Bapusaheb Patil"><img src="https://avatars.githubusercontent.com/u/16699418?u=6d9d8e0a64a6f91ca1c4d559c72d931172bdcbbd&v=4" width="32" height="32" alt="Bapusaheb Patil" /></a> | ||
| <a href="https://github.com/ripgrim?ref=orpc" target="_blank" rel="noopener" title="grim"><img src="https://avatars.githubusercontent.com/u/75869731?u=b17c42ec2309552fdb822a86b25a2f99146a4d72&v=4" width="32" height="32" alt="grim" /></a> | ||
| <a href="https://github.com/nelsonlaidev?ref=orpc" target="_blank" rel="noopener" title="Nelson Lai"><img src="https://avatars.githubusercontent.com/u/75498339?u=2fc0e0b95dd184c5ffb744df977cb15a18b60672&v=4" width="32" height="32" alt="Nelson Lai" /></a> | ||
| <a href="https://github.com/nguyenlc1993?ref=orpc" target="_blank" rel="noopener" title="Lê Cao Nguyên"><img src="https://avatars.githubusercontent.com/u/13871971?u=83c8b69d9e35b589c4e1f066cc113b1d9461386f&v=4" width="32" height="32" alt="Lê Cao Nguyên" /></a> | ||
| <a href="https://github.com/wobsoriano?ref=orpc" target="_blank" rel="noopener" title="Robert Soriano"><img src="https://avatars.githubusercontent.com/u/13049130?u=6d72104182e7c9ed25934815313fb69107332111&v=4" width="32" height="32" alt="Robert Soriano" /></a> | ||
| <a href="https://github.com/andrewpeters9?ref=orpc" target="_blank" rel="noopener" title="Andrew Peters"><img src="https://avatars.githubusercontent.com/u/36251325?v=4" width="32" height="32" alt="Andrew Peters" /></a> | ||
| <a href="https://github.com/R44VC0RP?ref=orpc" target="_blank" rel="noopener" title="Ryan Vogel"><img src="https://avatars.githubusercontent.com/u/89211796?u=1857347b9787d8d8a7ea5bfc333f96be92d5a683&v=4" width="32" height="32" alt="Ryan Vogel" /></a> | ||
| <a href="https://github.com/SKostyukovich?ref=orpc" target="_blank" rel="noopener" title="SKostyukovich"><img src="https://avatars.githubusercontent.com/u/10700067?v=4" width="32" height="32" alt="SKostyukovich" /></a> | ||
| <a href="https://github.com/peter-adam-dy?ref=orpc" target="_blank" rel="noopener" title="Peter Adam"><img src="https://avatars.githubusercontent.com/u/132129459?u=4f3dbbb3b443990b56acb7d6a5d11ed2c555f6db&v=4" width="32" height="32" alt="Peter Adam" /></a> | ||
| <a href="https://github.com/FabworksHQ?ref=orpc" target="_blank" rel="noopener" title="Fabworks"><img src="https://avatars.githubusercontent.com/u/160179500?v=4" width="32" height="32" alt="Fabworks" /></a> | ||
| <a href="https://github.com/NovakAnton?ref=orpc" target="_blank" rel="noopener" title="Novak Antonijevic"><img src="https://avatars.githubusercontent.com/u/157126729?u=ae49fa22292d55c0434ff0ca008206155b18663b&v=4" width="32" height="32" alt="Novak Antonijevic" /></a> | ||
| <a href="https://github.com/laduniestu?ref=orpc" target="_blank" rel="noopener" title="Laduni Estu Syalwa"><img src="https://avatars.githubusercontent.com/u/44757637?u=a2fc1ea8f7d827a96721176f79d30592d1c48059&v=4" width="32" height="32" alt="Laduni Estu Syalwa" /></a> | ||
| <a href="https://github.com/yukimotochern?ref=orpc" target="_blank" rel="noopener" title="Chen, Zhi-Yuan"><img src="https://avatars.githubusercontent.com/u/20896173?u=945c33fc21725e4d566a0d02afc54b136ca1d67a&v=4" width="32" height="32" alt="Chen, Zhi-Yuan" /></a> | ||
| <a href="https://github.com/illarionvk?ref=orpc" target="_blank" rel="noopener" title="Illarion Koperski"><img src="https://avatars.githubusercontent.com/u/5012724?u=7cfa13652f7ac5fb3c56d880e3eb3fbe40c3ea34&v=4" width="32" height="32" alt="Illarion Koperski" /></a> | ||
| <a href="https://github.com/steelbrain?ref=orpc" target="_blank" rel="noopener" title="Anees Iqbal"><img src="https://avatars.githubusercontent.com/u/4278113?u=22b80b5399eed68ac76cd58b02961b0481f1db11&v=4" width="32" height="32" alt="Anees Iqbal" /></a> | ||
| <a href="https://github.com/Scrumplex?ref=orpc" target="_blank" rel="noopener" title="Sefa Eyeoglu"><img src="https://avatars.githubusercontent.com/u/11587657?u=ab503582165c0bbff0cca47ce31c9450bb1553c9&v=4" width="32" height="32" alt="Sefa Eyeoglu" /></a> | ||
| <a href="https://github.com/nattstack?ref=orpc" target="_blank" rel="noopener" title="natt"><img src="https://avatars.githubusercontent.com/u/31426677?u=fa9dbb8b3e66eb0ea3c88db5dc07f31c8c5418fe&v=4" width="32" height="32" alt="natt" /></a> | ||
| <a href="https://github.com/ChromeGG?ref=orpc" target="_blank" rel="noopener" title="Adam Tkaczyk"><img src="https://avatars.githubusercontent.com/u/39050595?u=a58ca6042a6950e94e6e92442db76ef584279bc0&v=4" width="32" height="32" alt="Adam Tkaczyk" /></a> | ||
| <a href="https://github.com/plancraft?ref=orpc" target="_blank" rel="noopener" title="plancraft"><img src="https://avatars.githubusercontent.com/u/46482287?v=4" width="32" height="32" alt="plancraft" /></a> | ||
| <a href="https://github.com/Nic13Gamer?ref=orpc" target="_blank" rel="noopener" title="Nicholas"><img src="https://avatars.githubusercontent.com/u/54724556?u=56a7ab430ce7a80d648ab6eba051d454a818ed0b&v=4" width="32" height="32" alt="Nicholas" /></a> | ||
| </p> | ||
| ## License | ||
| Distributed under the MIT License. See [LICENCE](https://github.com/middleapi/standardserver/blob/main/LICENCE) for more information. |
61105
5.48%534
9.88%555
29.67%+ Added
- Removed
Updated