open-index/open-npm huggingface dataset:
npm package: @plotday/tool-google-drive
Description: Sync documents comments from Google Drive
Author: Plot
Latest version: 0.2.2
Deprecated: This package has been renamed. Sources are no longer published as npm packages.

# Google Drive Tool

A Plot tool for syncing documents comments from Google Drive.

## Installation

```bash
npm install @plotday/tool-google-drive @plotday/twister
```

## Usage

```typescript
import { GoogleDrive } from "@plotday/tool-google-drive";
import { Tools, Twist } from "@plotday/twister";
import {
  AuthProvider,
  Integrations,
} from "@plotday/twister/tools/integrations";

export default class extends Twist {
  private googleDrive: GoogleDrive;
  private integrations: Integrations;

  constructor(id: string, tools: Tools) {
    super();
    this.googleDrive = tools.get(GoogleDrive);
    this.integrations = tools.get(Integrations);
  }

  async activate(priority: { id: string }) {
    // Request Google Drive access
    const authLink = await this.integrations.request(
      {
        provider: AuthProvider.Google,
        scopes: GoogleDrive.SCOPES,
      },
      {
        functionName: "onAuthComplete",
        context: { priorityId: priority.id },
      }
    );

    // User will authenticate via authLink
  }
}
```

## Features

- OAuth 2.0 authentication with Google
- Folder-based document synchronization
- Comment and reply syncing
- Webhook-based change notifications
- Batch processing for large folders
- Bidirectional comment sync

## License

MIT © Plot Technologies Inc.
npm package: @plotday/tool-linear
Description: Sync with Linear project management
Author: Plot
Latest version: 0.7.1
Deprecated: This package has been renamed. Sources are no longer published as npm packages.

# Linear Tool for Plot

Sync your Linear teams and issues with Plot.

## Features

- OAuth authentication with Linear
- Sync issues from Linear teams to Plot activities
- Real-time updates via webhooks
- Issue comments synced as activity notes
- Automatic issue state mapping

## Usage

```typescript
import { Linear } from "@plotday/tool-linear";
import { Twist, type ToolBuilder } from "@plotday/twister";

export default class MyTwist extends Twist<MyTwist> {
  build(build: ToolBuilder) {
    return {
      linear: build(Linear),
    };
  }

  async activate() {
    // Request Linear authorization
    const authLink = await this.tools.linear.requestAuth(this.onAuthComplete);
    // ... show authLink to user
  }

  async onAuthComplete(auth: { authToken: string }) {
    // Get available teams
    const projects = await this.tools.linear.getProjects(auth.authToken);

    // Start syncing a team
    await this.tools.linear.startSync(
      auth.authToken,
      projects[0].id,
      this.onIssue
    );
  }

  async onIssue(issue: NewActivityWithNotes) {
    // Handle synced issue
    await this.tools.plot.createActivity(issue);
  }
}
```

## License

MIT
npm package: @plotday/tool-outlook-calendar
Description: Sync with Microsoft Outlook Calendar
Author: Plot
Latest version: 0.14.1
Deprecated: This package has been renamed. Sources are no longer published as npm packages.

# Outlook Calendar Tool

A Plot tool for syncing with Microsoft Outlook Calendar (Microsoft 365).

## Installation

```bash
npm install @plotday/tool-outlook-calendar @plotday/twister
```

## Usage

```typescript
import { Twist, Tools } from "@plotday/twister";
import { OutlookCalendar } from "@plotday/tool-outlook-calendar";
import { Integrations, AuthProvider } from "@plotday/twister/tools/integrations";

export default class extends Twist {
  private outlookCalendar: OutlookCalendar;
  private auth: Integrations;

  constructor(id: string, tools: Tools) {
    super();
    this.outlookCalendar = tools.get(OutlookCalendar);
    this.integrations = tools.get(Integrations);
  }

  async activate(priority: { id: string }) {
    // Request Outlook Calendar access
    const authLink = await this.integrations.request(
      {
        provider: AuthProvider.Microsoft,
        scopes: ["Calendars.Read"],
      },
      {
        functionName: "onAuthComplete",
        context: { priorityId: priority.id },
      }
    );

    // User will authenticate via authLink
  }

  async onAuthComplete(authorization: any, context: any) {
    const authToken = await this.integrations.get(authorization);

    // Get available calendars
    const calendars = await this.outlookCalendar.getCalendars(authToken);

    // Start syncing a calendar
    await this.outlookCalendar.startSync(
      authToken,
      calendars[0].id,
      "onCalendarEvent"
    );
  }

  async onCalendarEvent(event: any) {
    // Handle calendar events
    console.log("New calendar event:", event.subject);
  }
}
```

## API

### `getCalendars(authToken: string)`

Retrieves the list of calendars available to the authenticated user.

### `startSync(authToken: string, calendarId: string, callbackName: string, options?: object)`

Starts syncing events from an Outlook Calendar.

### `stopSync(authToken: string, calendarId: string)`

Stops syncing events from an Outlook Calendar.

## License

MIT © Plot Technologies Inc.
npm package: @plotdb/args
Description: Simple argument paser
Author: zbryikt
Latest version: 0.0.3

# @plotdb/args

Simple argument parser.

Usage:

    require("@plotdb/args")
    result = args({
      meta: {
        file: {alias: "f", type: "string", desc: "filename"},
        count: {alias: "c", type: "number", desc: "loop count"},
        verbose: {alias: "v", type: "boolean", desc: "verbose for debugging"},
      },
      onerror: function(e) { process.exit(); }
    });
    opt = result.options;
    console.log(
      opt.file, opt.f,
      opt.count, opt.count,
      opt.verbose, opt.v
    );


## Options

You can pass meta directly to args for simplicity:

    args({
        file: {alias: "f", type: "string", desc: "filename"},
        count: {alias: "c", type: "number", desc: "loop count"},
        verbose: {alias: "v", type: "boolean", desc: "verbose for debugging"},
    })

`@plotdb/args` recognize `meta` property in the given object to determine if it's a simplified parameter. When `meta` is given, you can specify more options:

    args({
      meta: { file: {...}, count: {...}, ...}, 
      argv: ...
      onerror: ...
    })

where:

 - `argv`: an alternative array of arguments to parse. default `process.argv` when omitted.
 - `onerror`: callback when parsing failed. silent exited (`process.exit()`) when omitted.


## License

MIT
npm package: @plotdb/chart
Description: plotdb charts
Author: zbryikt
Latest version: 3.0.0

# @plotdb/chart

@plotdb/chart is a charting framework that:

 - defines user / chart interface (including data, data/chart binding, style)
 - defines API interface (events or API for programmatically controlling charts)
 - provides handy charting tools for crafting your own charts
 - provides a chart preset that can be used out of the box.

You can also check [makechart](https://makechart.io) for an example of using @plotdb/chart on the fly.

In `@plotdb/chart`, charts are separated into 3 parts:

 - chart class - define how a chart works, and provide an interface for controlling charts.
 - chart mod - specific chart definition and implementation.
 - chart data - data, config, binding and other metadata.

Chart class provides:

 - chart lifecycle control - initing, resizing, rendering, destroying, etc
 - animation loop control.
 - rendering management for container resizing / visibility changing.
 - utility modules for common charting components.

Chart mod includes:

 - the actual code for chart rendering
 - definition of user configurable options
 - accepted data formats
 - other metadata and dependencies

While not in spec and not necessary, chart mod can be encapsulated in `@plotdb/block`.


## Usage

install via `@plotdb/chart`:

    npm install --save @plotdb/chart


include `@plotdb/chart` js and css files under `dist`, mainly `index.js` and `index.css`:

    <link rel="stylesheet" type="text/css" href="path-to-dist/index.min.css"/>
    <script src="path-to-dist/index.min.js"></script>


then, create and initialize a chart object:

    c = new chart({ ... })
    c.init().then(function() { ... });


For more detail about chart module object, chart object constructor option and api interface, check `doc/index.md`.

 
## Polyfill

ResizeObserver is used - consider using polyfill to support older browsers.


## License 

MIT
npm package: @plotdb/colors
Description: coloring output
Author: zbryikt
Latest version: 0.0.3

# @plotdb/colors

get colors in your node.js console.


## Installation

    npm install --save @plotdb/colors


## Usage

    require("@plotdb/colors")
    console.log("some colored text".red);
    console.log("some colored text with red background".bgRed.yellow);
    colors.disable(); /* colored outputs are disabled after this */
    console.log("some text without style / color".bgRed.yellow);
    colors.enable(); /* colored outputs are disabled after this */
    console.log("color is back".bgRed.yellow);
    colors.red("some red text");
    colors.green.underline("some red text"); /* recursively */
    colors.green.underline.red("some red text"); /* will be red. high priority for deeper styles */
 

## Colors and Styles

| fg      | bright fg     | bg        | bright bg       | styles        |
|---------|---------------|-----------|-----------------|---------------|
| black   | brightRed     | bgBlack   | bgBrightRed     | reset         |
| red     | brightGreen   | bgRed     | bgBrightGreen   | bold          |
| green   | brightYellow  | bgGreen   | bgBrightYellow  | dim           |
| yellow  | brightBlue    | bgYellow  | bgBrightBlue    | italic        |
| blue    | brightMagenta | bgBlue    | bgBrightMagenta | underline     |
| magenta | brightCyan    | bgMagenta | bgBrightCyan    | inverse       |
| cyan    | brightWhite   | bgCyan    | bgBrightWhite   | hidden        |
| white   |               | bgWhite   |                 | strikethrough |
| gray    |               | bgGray    |                 |               |
| grey    |               | bgGrey    |                 |               |


## Note

`@plotdb/colors` extends String.prototype directly which may not be a good approach.


## Reference

 - https://github.com/marak/colors.js/


## License

MIT
npm package: @plotdb/csscope
Description: add scope to any css code
Author: zbryikt
Latest version: 5.0.4

# csscope

add custom scope to any css. Use browser thus only works in browsers.


## Usage

install via npm:

    npm install --save @plotdb/csscope


then, include `csscope.js`, and convert css as follow:

    scopedCSS = csscope("desired-scope-name", "your-css-code")

or, with object as option:

    scopedCSS = csscope({css: "your css code", name: "desired-scope-name", scopeTest: "..."})

or, create a converter to convert:

    scope = new csscope.converter({ scopeTest: '...' });
    var scopedCSS = scope.convert({ ... });


options:

 - name: scope name. should be a valid name for CSS class and CSS animation name.
 - rule: optional. rule for matching the given scope name. by default `.your-scope-name`
 - scopeTest: optional. selector for testing boundary of scope.
 - css: css code to scope.


## Scope Testing

`scopeTest` is a css selector rule for which if certain node matches then it's the root of a scope.

This is used to identify scope boundary in DOM, according how users label and identify the root element of scopes by their implementation.

For example, following DOM ( in Pug ) use `[ld-scope]` to separate each scope:

    div(ld-scope,scope-id="0a2c92a0e7e82")
      h2 This is the root scope.
      div(ld-scope,scope-id="4c26846e44f68")
        h2 This is a child scope.

when we specify `scopeTest` option, we can ensure that the style for `h2` element in the parent won't affect `h2` element in its child.

`scopeTest` is by default `undefined` (or by default the value specified in option when calling `csscope.converter` constructor), in this case there is no scope boundary so all parent rules penetrate into their children.


## Scope Root

To style element of scope root, simply use `:scope` pseudo class:

    :scope { background: #000; color: #fff}

csscope will replace `:scope` with the corresponding scope selector.

## csscope.manager

use `csscope.manager` for managing library version and cache. usage:

    csm = new csscope.manager(options)

where `options` is an object with following posisble fields:

 - `registry`: a registry object telling manager how to fetch requested resource. can be either
   - a string. `csscope.manager` uses it as a root path to construct a resource URL.
   - a function accepting `{name, version, path}` parameters. return an URL for specific module
   - an object, with following fields:
     - `url({name, version, path})`: return an URL for specified item.
     - `fetch({name, version, path})`: optional, return `{version, content}` for specified item.
       - `version`: exact version of the returned content
       - `content`: content of the requested resource
   - for more information, check `@plotdb/block` and `@plotdb/registry` module.


## Pre bundling (WIP)

Generate js / css files and use `csscope.cache` to preload assets. 

Load from JS:

    csscope.cache({inited: false, code: 'scoped-css-code', scope: 'scope-name'});

Load from CSS:

    script csscope.cache({inited: true, scope: 'scope-name'});
    style: include bundle.css



## Todo

Test against all major browsers.


## License

MIT
npm package: @plotdb/datadom
Description: dom serializer / deserializer
Author: zbryikt
Latest version: 0.2.0

# datadom

DOM serializer / deserializer with scriptable plugins.

WIP, please consider this as an unstable library.


# Usage

install via npm:

    npm install --save @plotdb/datadom

Add `datadom.js` in your HTML:

    <script src="datadom.js"></script>


serialize/deserialize a DOM tree:

    json = datadom.serialize(document.querySelector("your-selector"), [])
    datadom.deserialize(json,[])
      .then({node, promise}) ->
        node # node is the deserialized DOM tree root.
        promise # promise for asynchronous content
      .then ({node, promise}) -> # all content prepared.

datadom is also a constructor:

    dd = new datadom({ ... })
    dd.init().then(function() { ... });


# API

constructor options:

 - `plugin`: function, of Array of functions as default plugin(s).
   - plugin function accepts 1 parameters: subtree root ( for serialize ) / subdoc root ( for deserialize )
 - `data`: datadom json
 - `node`: root of DOM tree. ignored if `data` is provided.
 - `window`: optional `window` object if run in NodeJS.

datadom object methods:

 - `init()`: initialize data and node ( from provided counterpart ). Return promise.
 - `update(ops)`: apply ops ( operation transformations ) to internal data and DOM tree.
 - `getData()`: return datadom json.
 - `getNode()`: return root of the corresponding DOM tree.

datadom class methods:

 - `serialize(node, plugin)`: convert DOM tree (with root `node`) into json.
   - `node`: root node of DOM tree to serialize
   - `plugin(d)`: optional handler for custom node types.
 - `deserialize(data, plugin)`: convert datadom json into DOM tree
   - `data`: a datadom json.
   - `plugin(d)`: optional handler for custom node types.


## Node.js

to run in nodeJS, use `jsdom` and pass `window` as an argument:

    datadom.deserialize(data, [], (new JSDOM()).window);

similarly, pass `window` in constructor when using `new datadom( ... )`:

    new datadom({ ..., window: (new JSDOM()).window)});


## Plugins

(TBD) check `doc/plugin.md` for more information.


# License

MIT
npm package: @plotdb/datum
Description: data manipulation library
Author: zbryikt
Latest version: 0.1.4

# @plotdb/datum

Data manipulation library.

To manipulate data, we have following concepts:

 - `dataset` - set of data in specific format.
 - `type` - data type of a dataset column.
 - `dimension definition` - defining what is needed (such as data type) for certain purpose.
 - `binding` - define the binding between dataset and dimension.

For `dataset`, see `doc/dataset.md` for more information. For the reset ( type, dimension and binding ), see `binding.md` for more information.


## Installation

Install via npm:

    npm install --save @plotdb/datum


and include the js file:

    <script src="path/to/datum/index.min.js"></script>


Create a `datum` object:

    var d = new datum( ... );


## License

MIT
npm package: @plotdb/form
Description: form blocks
Author: zbryikt
Latest version: 0.1.2

# @plotdb/form

Form related modules for interactive form design throught GUI, with following (expected, TODO) features:

 - design a form through GUI.
 - designed form serializable and renderable in frontend for end users to fill.
 - end user filled result of a form is also serializable.
 - Aware of OT for collaborative editing.
 - Works in both frontend and backend.


`@plotdb/form` includes following modules:

 - `form.manager`: manage a set of form widgets.
 - `form.widget`: interface between form manager and UI.
 - `form.opset`: a set of op for validating given input from user.
 - `form.op`: a specific operation for validating given input from user.
 - `form.term`: a rule ( a op, opset and config based on the specified op ) for validating given input from user.


## Draft

### form.block attrubite

An attribute is an aspect of data from a form.block. For example, a File form.block could contains following attributes:

 - `size` - size of all files combined.
 - `count` - count of files.
 - `modifiedtime` - modified time of last touched files.
 - `ext` - type of files.

Every attribute can be associated with one or multiple `form.opset` For example, above `ext` attribute can be associated with `extensions` type, which helps in determining if files in a given `ext` array all belong to certain file type.
npm package: @plotdb/h264.mp4
Description: check if a file is encoded in MPEG-4 / H.264.
Author: zbryikt
Latest version: 0.0.2

# @plotdb/h264.mp4

check if a file is encoded in MPEG-4 / H.264.


## Usage

install:

    npm install --save @plotdb/h264.mp4

include and init `h264`:

    codec = new h264 worker-url: ...
    codec.init!
      .then -> codec.check(fileobj)
      .then -> # support
      .catch -> # not support


## License

MIT
npm package: @plotdb/har-validator
Description: Extremely fast HTTP Archive (HAR) validator using JSON Schema
Author: Ahmad Nassri
Latest version: 5.1.6

# @plotdb/har-validator

This is a fork version of original [node-har-validator](https://github.com/ahmadnassri/node-har-validator). Original module is not maintained, but what the module does is quite simple and mostly relies on another module `ajv`. so we simply fork it and maintain this by ourselves.

----

# Har Validator

[![license][license-img]][license-url]
[![version][npm-img]][npm-url]
[![super linter][super-linter-img]][super-linter-url]
[![test][test-img]][test-url]
[![release][release-img]][release-url]

[license-url]: LICENSE
[license-img]: https://badgen.net/github/license/ahmadnassri/node-har-validator

[npm-url]: https://www.npmjs.com/package/har-validator
[npm-img]: https://badgen.net/npm/v/har-validator

[super-linter-url]: https://github.com/ahmadnassri/node-har-validator/actions?query=workflow%3Asuper-linter
[super-linter-img]: https://github.com/ahmadnassri/node-har-validator/workflows/super-linter/badge.svg

[test-url]: https://github.com/ahmadnassri/node-har-validator/actions?query=workflow%3Atest
[test-img]: https://github.com/ahmadnassri/node-har-validator/workflows/test/badge.svg

[release-url]: https://github.com/ahmadnassri/node-har-validator/actions?query=workflow%3Arelease
[release-img]: https://github.com/ahmadnassri/node-har-validator/workflows/release/badge.svg

> Extremely fast HTTP Archive ([HAR](https://github.com/ahmadnassri/har-spec/blob/master/versions/1.2.md)) validator using JSON Schema.

## Install

```bash
npm install har-validator
```

## CLI Usage

Please refer to [`har-cli`](https://github.com/ahmadnassri/har-cli) for more info.

## API

**Note**: as of [`v2.0.0`](https://github.com/ahmadnassri/node-har-validator/releases/tag/v2.0.0) this module defaults to Promise based API.
_For backward compatibility with `v1.x` an [async/callback API](docs/async.md) is also provided_

- [async API](docs/async.md)
- [callback API](docs/async.md)
- [Promise API](docs/promise.md) _(default)_
npm package: @plotdb/httputil
Description: util functions for http and browser context
Author: zbryikt
Latest version: 0.0.7

# httputil

utility functions for commonly used http and browser context related functions, including:

 - `cookie(key,value,opt)` - getter / setter of cookie.
   - if `value` is omitted, return the cookie corresponding to `key`.
   - return undefined if `key` is not found in cookie.
   - option: either a string for expiration date, or an object with cookie options such as:
     - `expires`
     - `max-afge`
     - `path`
 - `qs(key)` - get value for `key` in querystring
   - return key-value pair hash if key is omitted.
   - return composed query string if `key` is a hash for key-value pairs.
   - return undefined if `key` is not found in query string.
 - `datefmt(date, opt)` - date object formatter.
   - return a date string in `YY/MM/DD hh:mm:ss` format.
   - parameters:
     - `date`: either a number (epoch) or a Date object. Use `new Date()` if omitted.
     - `opt`: an option object with following fields:
       - `time`: show time if true. Default true if omitted.
       - `invalid`: placeholder text when the given date is invalid. `undefined` will be used if omitted.


# License

MIT
npm package: @plotdb/ipfrom
Description: for a quick structural ip address of taiwan.
Author: zbryikt
Latest version: 0.0.3

# @plotdb/ipfrom

A simple tool to determine if an ip address is from Taiwan.
While this repo is named as `@plotdb/ipfrom`, it only support determining taiwan IPs for now. This naming preserves future extensibility.


## Data Source

 - https://rms.twnic.tw/help_ipv4_assign.php
 - https://rms.twnic.tw/help_ipv6_assign.php

to fetch again, generate `table.ls` by running `tool/fetch` and move generated `table.ls` into `src/` folder.


## License

MIT
npm package: @plotdb/json0
Description: json0 ( ot + diff ) modules bundle 
Author: zbryikt
Latest version: 0.0.5

# json0

bundle of `ot-json0`, `json0-ot-diff` and `diff-match-patch` for browser.


# Usage

include `dist/json0.min.js` and use it as:

    /* diff 2 objects, return operational transformations */
    json0.diff(objA, objB)

    /* github:ottypes/json0 */
    json0.type 

    /* apply ot with json0.type */
    json0.type.apply(objC, ots);


for a module version, use `dist/require/json0.min.js`:

    json0 = require("json0")


# Version

we lock `deep-equal` to version 1.0.1 to prevent `es-abstract` from being bundled together, which induces 30k+ file size.


# License 

MIT
npm package: @plotdb/mail-queue
Description: for queuing mails and mail templating
Author: zbryikt
Latest version: 0.0.2

# @plotdb/mail-queue

for queuing mails and mail templating



## Sample Template

use `yaml` format and `markdown` for `content`:

    from: '"#{orgname} Support" <noreply@#{domain}>'
    subject: 'Email Verification / #{domain}'
    content: |
      Hi #{username}!

      This is an email verification mail because someone used your email to sign up in #{domain} and requested an email verifiction.

      To verify your email, please open following link:

      [https://#{domain}/mail/verify/#{token}](https://#{domain}/mail/verify/#{token})

      This is an automatically generated mail so please don't reply in case that no one receive your mail.

      Best regards,
      #{orgname} team

possible fields:

 - `from`
 - `to`
 - `bcc`
 - `cc`
 - `subject`
 - `content`


## License

MIT
npm package: @plotdb/pdmap-world
Description: World map in D3js and ISO 3166 country code
Author: zbryikt
Latest version: 0.0.5

# pdmap-world

World map in D3js and ISO 3166 country code. 


## Usage

include required JS files:

    <script src="https://d3js.org/d3.v4.js"></script>
    <script src="https://d3js.org/topojson.v2.min.js"></script>
    <script src="path-to-your-pdmap-world.js"></script>

then, init with following:

    p = new pdmapWorld({ ... })
    p.init().then(function() {  p.fit();  ...  })


country paths will be added under a SVG `g` element with `pdmap-world` class. pdmap-world only draws countries. To further visualize your data, you have to do it yourself, such as:

    # if you call `p.set` first:   
    d3.select(root).selectAll("path")
      .attr "fill", (d,i) ~>
        v = d.properties.value or 0
        if v <= 0 => return \#eee
        "rgb(#{255 * (d.properties.value or 0) / p.range!},0,0)"

    # or bind data with country yourself:
    d3.select(root).selectAll("path")
      .attr "fill", (d,i) ~>
        v = data[d.properties.alpha2]
        if v <= 0 => return \#eee
        "rgb(#{255 * (v) / max},0,0)"


## Constructor options

 - `root`: container element.
 - `excludes`: Array of country identifiers ( see below ). countries listed here will not be shown.
 - `includes`: Array of country identifiers ( see below ). countries not listed here will not be shonw.
   - when `includes` is set, `excludes` will be ignored.
 - `padding`: padding space between container and map shapes.
 - `popup`: handler called when mouse hovering on shapes.


## API

 - `init()`: initialization.
 - `set(hash)`: set values for each country. country name as key in hash, value as value in hash.
 - `range()`: get `[minimal, maximal]` values from `set` calls.
 - `allCountries()`: get a list of all countries.
 - `fit()`: fix map to size of container.
 - `findCountry(n)`: return a country object according to country identifier `n` ( see below )


## Country Identifiers

There are many ways to identify a country. Here we use following identifiers:

 - iso 3166 country code, including:
   - Alpha-2 code ( e.g., `KP` for North Korea, `GB` for United Kingdon. )
   - Alpha-3 code ( e.g., `USA` for United States, `JPN` for Japan )
   - Short name ( e.g., `Afghanistan`, `Congo (the)` )
   - Numeric ( e.g., `156` for China, `524` for Nepal )
 - Common name in zh-TW ( e.g., `阿爾巴尼亞`, `波希尼亞及赫塞哥維那` )

Following is an example to refer some countries with a list, which can be used as `excludes` / `includes` option:

    ["KP", "USA", "Afghanistan", 156, "波希尼亞及赫塞哥維那"]

All codes are case insensitive.


## Data Resources

 - map data: [natural-earth-vector](https://github.com/nvkelso/natural-earth-vector)
 - country code: [iso 3166 country codes](https://www.iso.org/iso-3166-country-codes.html)


## License

 - Code: MIT
 - Data: 
   - map data: Public Domain
   - country code: should be(?) Public Domain
npm package: @plotdb/qrcode
Description: QRCode Generator
Author: zbryikt
Latest version: 0.0.2

# @plotdb/qrcoder

## Usage


    svg-string = qrcoder.svg("some text")



## License

MIT

Additionally, `src/core.js` is adopted from following repo:

 - https://github.com/davidshimjs/qrcodejs, author: davidshimjs (MIT License)

qrcodejs itself is adopted from `QRCode for JavaScript` by Kazuhiko Arase (MIT License)
 
    QRCode for JavaScript
    Copyright (c) 2009 Kazuhiko Arase
    URL: http://www.d-project.com/
    Licensed under the MIT license:
      http://www.opensource.org/licenses/mit-license.php
    The word "QR Code" is registered trademark of 
    DENSO WAVE INCORPORATED
      http://www.denso-wave.com/qrcode/faqpatent-e.html
npm package: @plotdb/quill-uploader
Description: Upload Manager for Quill.js. It's a abstract interface for which you should still implement the upload function to handle the upload request.
Author: zbryikt
Latest version: 0.0.2

# @plotdb/quill-uploader

Upload Manager for Quill.js. It's a abstract interface for which you should still implement the upload function to handle the upload request.


## Installation

Install @plotdb/quill-uploader and its dependencies via npm:

    npm install --save @plotdb/quill-uploader ldfile @loadingio/debounce.js


## Usage

include js file:

    <script type="module" src="path/to/quill-uploader/dist/index.min.js"></script>


create a quill-uploader instance:

    uploadr = new quillUploader(opt)

where `opt` is an object with the following properties:

 - `upload`: a function that handles upload request.
   - request is handled  by accepting an object with following params:
       - `file`: file blob to upload which should provide following fields:
         - `name`, `size`, `type`, `lastModified`
       - `progress`: a callback function that accepts upload progress between 0 ~ 1.
   - it should return a Promise which resolves with an object with following fields:
     - `filename`: file name.
     - `size`: file size.
     - `modifiedtime`: last modified time of this file.
     - `url`: where we can find the uploaded version of this file.


then, use it to construct a Quill instance:

    new Quill(node, {
      modules: { toolbar: {
        handlers: {
          image: uploadr.handler.upload({type:"image"}),
          upload: uploadr.handler.upload({type:"file"})
        }
      }}
    })

and watch for `uploaded` event which will be fired with a file blob object when the file is successfully uploaded:

    uploader.on("uploaded", function(file) { ... });


## License

MIT
npm package: @plotdb/sandbox
Description: sandboxing user generated code in frontend iframe
Author: zbryikt
Latest version: 0.0.3

# sandbox.js

Sandboxing javascript in embedded iframe.


## Usage

var sb = new sandbox(config);

## Configurations

 * root - root element. sandbox.js will create one if this is omitted.
 * container - if root is not specified or root doesn't have a parent, attach root to container.
   default to document.body if both root and container are omitted.
 * sandbox - iframe sandbox attributes. default to "allow-scripts allow-pointer-lock".
   Note: blob iframe in Firefox exploits host cookie with empty sandbox.
 * className: space separated class list to add over the root element.
 * window - works in standalone popup window. root and container won't be necessary when window provided.
   window, if provided, should be an object containing following members:
   - name - window name. randomly generated if omitted.
   - width - window width. decided by sandbox.js if omitted.
   - height - window height. decided by sandbox.js if omitted.


## Methods

 * setProxy(({obj: obj}) - set an object as proxy interface. Proxy object must passed in an object like:

   ```
   sb.setProxy({ Interface: Interface });
   ```

   once set, you can invoke corresponding object in sandbox with following:

   ```
   sb.proxy.someFunc(args);
   ```

   you must have the object ( e.g., Interface ) with the exact same name as a global object in sandbox context.

 * send(msg) - send message to sandbox. msg will be wrapped in an object as:

   ```
   { type: \msg, payload: your-msg-data }
   ```

 * reload() - reload sandbox.
 * load(payload) - initialize sandbox content. payload can be a plain string or has following structure:

   ```
   {
      "html": (string or {url: HTML-URL} ),
      "css":  (string or {url: CSS-URL} ),
      "js":   (string or {url: JS-URL} )
   }
   ```
 * openWindow(cfg) - open sandbox in a standalone window.
   - cfg.name - window name.


## Sample Usage

iframe mode:
```
    /* create a sandbox instance */ 
    var sb = new sandbox({
      container: 'selector-for-certain-node',
      className: 'space separated class names'
    });

    /* load and render code */
    sb.load({js: '...', html: '...', css: '...'});

    /* you can still render it again in a standalone window */
    sb.openWindow({name: "window-name"})
      .then(function() { ... });
```

window mode:
```
    /* create a sandbox instance */ 
    var sb = new sandbox({
      window: 'window-name'
    });

    /* load and render code */
    sb.load({js: '...', html: '...', css: '...'});
```

you can also init with both modes:
```
    /* create a sandbox instance */ 
    var sb = new sandbox({
      window: 'window-name',
      container: 'selector-for-certain-node'
    });
```

## Resources

 - how figma support plugins: https://www.figma.com/blog/how-we-built-the-figma-plugin-system/


## License

MIT
npm package: @plotdb/sandbox.js
Description: sandboxing user generated code in frontend iframe
Author: Kirby Wu
Latest version: 0.0.1

# sandbox.js

Sandboxing javascript in embedded iframe.


## Usage

var sandbox = new Sandbox(config);

## Configurations

 * root - root element. sandbox.js will create one if this is omitted.
 * container - if root is not specified or root doesn't have a parent, attach root to container.
   default to document.body if both root and container are omitted.
 * sandbox - iframe sandbox attributes. default to "allow-scripts allow-pointer-lock".
   Note: blob iframe in Firefox exploits host cookie with empty sandbox.
 * className: space separated class list to add over the root element.
 * window - works in standalone popup window. root and container won't be necessary when window provided.
   window, if provided, should be an object containing following members:
   - name - window name. randomly generated if omitted.
   - width - window width. decided by sandbox.js if omitted.
   - height - window height. decided by sandbox.js if omitted.


## Methods

 * setProxy(({obj: obj}) - set an object as proxy interface. Proxy object must passed in an object like:

   ```
   sandbox.setProxy({ Interface: Interface });
   ```

   once set, you can invoke corresponding object in sandbox with following:

   ```
   sandbox.proxy.someFunc(args);
   ```

   you must have the object ( e.g., Interface ) with the exact same name as a global object in sandbox context.

 * send(msg) - send message to sandbox. msg will be wrapped in an object as:

   ```
   { type: \msg, payload: your-msg-data }
   ```

 * reload() - reload sandbox.
 * load(payload) - initialize sandbox content. payload can be a plain string or has following structure:

   ```
   {
      "html": (string or {url: HTML-URL} ),
      "css":  (string or {url: CSS-URL} ),
      "js":   (string or {url: JS-URL} )
   }
   ```
 * openWindow(cfg) - open sandbox in a standalone window.
   - cfg.name - window name.


## Sample Usage

iframe mode:
```
    /* create a sandbox instance */ 
    var sandbox = new Sandbox({
      container: 'selector-for-certain-node',
      className: 'space separated class names'
    });

    /* load and render code */
    sandbox.load({js: '...', html: '...', css: '...'});

    /* you can still render it again in a standalone window */
    sandbox.openWindow({name: "window-name"})
      .then(function() { ... });
```

window mode:
```
    /* create a sandbox instance */ 
    var sandbox = new Sandbox({
      window: 'window-name'
    });

    /* load and render code */
    sandbox.load({js: '...', html: '...', css: '...'});
```

you can also init with both modes:
```
    /* create a sandbox instance */ 
    var sandbox = new Sandbox({
      window: 'window-name',
      container: 'selector-for-certain-node'
    });
```


## License

MIT
npm package: @plotdb/semver
Description: semantic version range analyzer
Author: zbryikt
Latest version: 0.0.3

# @plotdb/semver

semantic version utility.

(TBD) there has been some similar implementations. We probably should use them instead?


## Installation

    npm install --save @plotdb/semver


## Usage

    require! <[@plotdb/semver]>
    semver.fit "1.5.0", "^1.3.2" # true
    semver.fit "1.5.0", "~1.3.2" # false


## License

MIT
npm package: @plotdb/sharedb-postgres
Description: PostgreSQL adapter for ShareDB. forked from share/sharedb-postgres
Author: Jeremy Apthorp
Latest version: 4.0.1

# @plotdb/sharedb-postgres

PostgreSQL database adapter for [sharedb](https://github.com/share/sharedb). This driver can be used both as a snapshot store and oplog.

Doesn't support queries (yet?).

Moderately experimental. (This drives [Synaptograph](https://www.synaptograph.com)'s backend, and [@nornagon](https://github.com/nornagon) hasn't noticed any issues so far.)


## Note about versioning

This is a fork from the [original `sharedb-postgres`](https://github.com/share/sharedb-postgres) and its relative forks (see [billwashere](https://github.com/billwashere/sharedb-postgres-jsonb), [zbryikt](https://github.com/zbryikt/sharedb-postgres-jsonb). It seems to have been not maintained for a long time since 2018, Thus we decide to fork it and maintain it as `@plotdb/sharedb-postgre`.


## Requirements

Due to the fix to resolve [high concurency issues](https://github.com/share/sharedb-postgres/issues/1) Postgres 9.5+ is now required.

## Migrating older versions

Older versions of this adaptor used the data type json. You will need to alter the data type prior to using if you are upgrading. 

```PLpgSQL
ALTER TABLE ops
  ALTER COLUMN operation
  SET DATA TYPE jsonb
  USING operation::jsonb;

ALTER TABLE snapshots
  ALTER COLUMN data
  SET DATA TYPE jsonb
  USING data::jsonb;
```

## Usage

`sharedb-postgres-jsonb` wraps native [node-postgres](https://github.com/brianc/node-postgres), and it supports the same configuration options.

To instantiate a sharedb-postgres wrapper, invoke the module and pass in your
PostgreSQL configuration as an argument or use environmental arguments. 

For example using environmental arugments:

```js
var db = require('sharedb-postgres')();
var backend = require('sharedb')({db: db})
```

Then executing via the command line 

```
PGUSER=dbuser  PGPASSWORD=secretpassword PGHOST=database.server.com PGDATABASE=mydb PGPORT=5433 npm start
```

Example using an object

```js
var db = require('sharedb-postgres')({host: 'localhost', database: 'mydb'});
var backend = require('sharedb')({db: db})
```

## Error codes

PostgreSQL errors are passed back directly.

## Changelog

Note that version 3.0.0 introduces breaking changes in how you specify
connection parameters. See the [changelog](CHANGELOG.md) for more info.
npm package: @plotdb/stylus-browser
Description: Builder for Stylus running in browser
Author: zbryikt
Latest version: 0.0.3

# stylus-browser

browserify stylus, with minimized js file sized 286KB.


## Size comparison

 - [bundle file](https://stylus-lang.com/try/stylus.min.js) from [stylus-lang.com](https://stylus-lang.com): < 200KB ( 0.54.5 )
 - bundle from [stylus-lang-bundle](https://github.com/openstyles/stylus-lang-bundle): < 200KB ( 0.54.7 )
   - somehow failed to rebuild with latest dev.
   - fs shimmed.
 - our bundle: 286KB ( 0.57.0 )

bundle components analysis is available under `web/static/discify/index.html`.


## License

MIT License.

 - this repo is released under MIT License
 - Stylus itself is released under MIT License.
 - Some shims used in this repo are adopted from [openstyles/stylus-lang-bundle](https://github.com/openstyles/stylus-lang-bundle), which are released under MIT license.
npm package: @plotdb/suuid
Description: short uuid with timestamp
Author: zbryikt
Latest version: 0.5.1

# suuid

short, sortable uuid. convert uuid into base 64 string along with coded timestamp.



## Usage

    <script src="<path-to>/suuid.bundle.min.js"></script>
    <script>
      var id = suuid();
      var ts = suuid.timestamp(id);
      var short = suuid.encode("abc0123");
    </script>

sample output ( try with `test/gen.ls` ):

    generated suuid: OTeyNTN4r9fi49Wc5M.AsIMZT0NCe4
    timestamp: 1611282605846 ( Fri Jan 22 2021 10:30:05 GMT+0800 (Taipei Standard Time) )


## API

 - `suuid(opt)`: randomly return a suuid if `opt` is omitted. otherwise, `opt` can be:
   - a `base16` string: return encoded corresponding string.
   - an object `{id, timestamp}`: return an encoded `id` prefix with timestamp, if `timestamp` is true.
     - `id`: a base16 string to encode.
     - `timestamp`: true if prefix timestamp before encoded id. default true.
 - `suuid.timestamp(id)`: get timestamp ( in epoch unix timestamp ) from given suuid
 - `suuid.encode(s)`: simply encode a `base16` string to `base64` string ( with our charmap, see below )


## Spec

`suuid` does following things:

 - prefix uuid(v4) with epoch unix timestamp
 - remove separator ( dash ) in uuid.
 - encodes values from hexadecimal to 64-based string with following charmap: ( url-safe chars according to [the latest uri spec](https://tools.ietf.org/html/rfc3986)

    `123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0_.`


while length of codes corresponding to uuid part are fixed, length of the timestamp code varys. The timestamp bits will be:

 - 7 bytes long before 2109AD
 - 8 bytes long before 10895AD
 - 9 bytes long before 573202AD

and the length of remaining part ( coded uuid, for randomness ) will be always 23 bytes long. thus, to sort suuid before 573202AD, simply add padding zeros before id to make it 32 bytes long.


## Comparison

 - [uniqid](https://github.com/adamhalasz/uniqid)
   - 18 bytes
   - no timestamp

 - [ulid](https://github.com/ulid/spec)
   - 48-bit timestamp + 80-bit entropy
   - base32 encoding, fixed length ( 26 character string. )
     - avoiding similar chars ( like `1IiJj` ) and is case insensitive.
   - timestamped ( 1ms precision )
     - overflow after 10889AD

 - [ksuid](https://github.com/segmentio/ksuid)
   - 32-bit timestamp + 128-bit entropy
   - base62 encoding ( `0-9a-zA-Z` ), fixed length ( 27 characters string. )
   - timestamped ( 1s precision )
     - offset to start from `2014-03-05`
     - overflow after 2150AD

 - [@plotdb/suuid](https://github.com/plotdb/suuid)
   - varied length timestamp ( 42-bit+ ) + 128-bit entropy
   - base64 encoding ( `0-9a-zA-Z.-` ), varied length ( 30 characters + )
   - timestamped ( 1ms precision )
     - unix epoch timestamp ( since `1970-01-01` )

 - [uuid v6 proposal](http://gh.peabody.io/uuidv6/)
   - TBD
   - try to add timestamp in uuid.
   - just a draft, and was expired.
   - [Github Repo](https://github.com/uuid6/uuid6-ietf-draft)


## License

MIT
npm package: @plotdb/xfl
Description: make quick and dynamic CJK web font
Author: zbryikt
Latest version: 0.0.1

xl-fontload
=======

中文字型網路化。 依詞頻切割字型，並透過前端實作 lazy loading。 無需後端程式支援。

 * 字頻檔 ( word-frequency.csv )
   示範檔來源: [教育部](http://language.moe.gov.tw/001/Upload/files/SITE_CONTENT/M0001/86NEWS/download/86rest17.TXT)
 * 列舉轉換字型. 放置在 fonts/ 目錄, 結構不拘. 自動搜尋所有 .ttf 結尾檔案.
 * 針對每一字型:
   * 列舉所有支援字符
   * 其中常用五百字、標點符號、英文字母、數字等，做為第一字型檔
   * 接下來，剩餘字符有出現在詞頻表中者，依字頻每一百字組成一字型檔.
   * 剩餘未對應字，每一百字組成一字型檔.
   * 所有字型檔置於同一目錄中，檔名以數字區隔.
   * 輸出字碼 / 字型檔編號對應表, 供前端快查.



Usage / Compiler
----------------

 * 此專案使用 nodejs, 請先安裝 nodejs 與 npm ，並利用 npm install 建利 node_modules 目錄。
   參考指令: 

       curl -sL https://deb.nodesource.com/setup_8.x | sudo bash -
       npm install

 * 將欲轉換的字型整理至 fonts/ 目錄，目錄結構不拘。程式會自動掃出所有字型檔。
   - 目前只吃 ttf 檔唷～啾咪。
 * 準備字型檔 word-frequency.csv
 * 執行轉換程式 compile.sh 
 * 字型檔輸出於 assets/ 目錄.



Usage / Frontend
----------------

基本使用方式：

    xfl.load("http://path/to/scattered/font/folder/", options, function(font) {
        font.sync(stringToDisplay);
    })


根據即時內容動態載入字型的範例：

    /* assume we have "textarea" variable to be an input box accepting user input */
    xfl.load("http://path/to/scattered/font/folder/", options, function(font) {
       textarea.addEventListener("keyup", function() {
         font.sync(textarea.value);
       });
    })


若你沒有打算自幹字型檔，可以使用我們透過 Github Pages 準備的一組字型檔，專案庫的位置在[這裡](https://github.com/plotdb/xl-fontset/)，欲使用則可以透過這個網址：[http://plotdb.github.io/xl-fontset/alpha/<字型名稱>](http://plotdb.github.io/xl-fontset/alpha/<字型名稱>)，例如：

    xfl.load("http://plotdb.github.io/xl-fontset/alpha/瀨戶字体", function(font) { ...

請自行將「<字型名稱>」換成欲使用的字型即可。目前支援的字型一覽可在[這裡](https://github.com/plotdb/xl-fontset/tree/gh-pages/alpha)找到，包括王漢宗 42 字型、刻石錄、站酷、cwText-Q、瀨戶字体等共 57 種字型。

要注意的是目前字型檔轉換時仍有些問題，可能因此導致部份字型有缺字狀況。此外並非所有字型都包含了完整的中文字，請自行斟酌使用。


Options:

  * fontName - name used in font-family. default to be the basename of URL.
  * (TBD) text - preload files that contains text in this option.



未來方向
--------

 * 傳輸最佳化 ( Optimization )
   * 考慮到字符相關性，可透過萌典、特定語料庫建立字符空間，透過 clustering algorithm ( 如 K-means clustering ) 將相關字符分組做為字型切割依據，進而減少需要載入的檔案數量.
   * 進一步做檔案尺寸最佳化。
   * 提供 nginx 與 apache 組檔模組，讓瀏覽器可以透過單一 HTTP Request 取得必要檔案 ( 例如, GET https://path/to/font/1+2+3+4 ) 
 * 品質問題 ( Quality )
   * 缺字部份，可使用對抗式生成網路學習並自動補齊。
   * 上述的對抗式生成網路亦可用於協助新字型生成。
 * 其它
   * 設定參數化，在建立字型檔時可透過設定依自己的需求客製化字型集。
 * Google Font 已實作類似的技術用以載入中文字型. 請參見:
   - https://developers.google.com/web/fundamentals/performance/optimizing-content-efficiency/webfont-optimization
   - 範例 CSS:
     - https://fonts.googleapis.com/css?family=Zhi-Mang-Xing&display=swap


LICENSE
--------

 * Font Files: All curated font files are separatedly placed in [another repo (xl-fontset)](https://github.com/plotdb/xl-fontset/) and are either GPL or SIL-OFL Licensed. (OK for Commercial Use)
 * Source codes are released under MIT License.