diff --git a/.gitignore b/.gitignore
index bf816f96..410eb3a8 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,6 +1,5 @@
node_modules
build
-impro-plugin/docs
.env
.context
tests/e2e/.results
diff --git a/.husky/pre-commit b/.husky/pre-commit
index bad1522c..cb74d68e 100755
--- a/.husky/pre-commit
+++ b/.husky/pre-commit
@@ -1 +1,7 @@
-npm run format && npm run test:unit
\ No newline at end of file
+npm run format && npm run test:unit
+
+# Rebuild plugin docs if source changed
+if git diff --cached --name-only --diff-filter=ACMR | grep -q '^impro-plugin/main\.js$'; then
+ npm run docs --prefix impro-plugin
+ git add impro-plugin/docs
+fi
diff --git a/impro-plugin/docs/docs.md b/impro-plugin/docs/docs.md
new file mode 100644
index 00000000..717333c8
--- /dev/null
+++ b/impro-plugin/docs/docs.md
@@ -0,0 +1,1851 @@
+# @impro.social/impro-plugin
+
+## Classes
+
+### App
+
+#### Properties
+
+| Property | Type |
+| ----------------------------------------------- | --------------------------- |
+| `currentUser` | `any` |
+| `data` | [`PluginData`](#plugindata) |
+
+#### Methods
+
+##### blockActor()
+
+> **blockActor**(`did`): `Promise`\<`any`\>
+
+###### Parameters
+
+| Parameter | Type |
+| --------- | ----- |
+| `did` | `any` |
+
+###### Returns
+
+`Promise`\<`any`\>
+
+##### muteActor()
+
+> **muteActor**(`did`): `Promise`\<`any`\>
+
+###### Parameters
+
+| Parameter | Type |
+| --------- | ----- |
+| `did` | `any` |
+
+###### Returns
+
+`Promise`\<`any`\>
+
+##### on()
+
+> **on**(`event`, `listener`): `void`
+
+###### Parameters
+
+| Parameter | Type |
+| ---------- | ----- |
+| `event` | `any` |
+| `listener` | `any` |
+
+###### Returns
+
+`void`
+
+##### refreshFeedFilters()
+
+> **refreshFeedFilters**(`feedURI?`): `Promise`\<`any`\>
+
+###### Parameters
+
+| Parameter | Type | Default value |
+| --------- | ----- | ------------- |
+| `feedURI` | `any` | `null` |
+
+###### Returns
+
+`Promise`\<`any`\>
+
+##### showLessLikeThis()
+
+> **showLessLikeThis**(`postUri`, `feedUri`): `Promise`\<`any`\>
+
+###### Parameters
+
+| Parameter | Type |
+| --------- | ----- |
+| `postUri` | `any` |
+| `feedUri` | `any` |
+
+###### Returns
+
+`Promise`\<`any`\>
+
+##### showMoreLikeThis()
+
+> **showMoreLikeThis**(`postUri`, `feedUri`): `Promise`\<`any`\>
+
+###### Parameters
+
+| Parameter | Type |
+| --------- | ----- |
+| `postUri` | `any` |
+| `feedUri` | `any` |
+
+###### Returns
+
+`Promise`\<`any`\>
+
+##### unblockActor()
+
+> **unblockActor**(`did`): `Promise`\<`any`\>
+
+###### Parameters
+
+| Parameter | Type |
+| --------- | ----- |
+| `did` | `any` |
+
+###### Returns
+
+`Promise`\<`any`\>
+
+##### unmuteActor()
+
+> **unmuteActor**(`did`): `Promise`\<`any`\>
+
+###### Parameters
+
+| Parameter | Type |
+| --------- | ----- |
+| `did` | `any` |
+
+###### Returns
+
+`Promise`\<`any`\>
+
+---
+
+### BlobImageComponent
+
+#### Properties
+
+| Property | Type |
+| ----------------------------- | ----- |
+| `el` | `any` |
+
+#### Methods
+
+##### setAlt()
+
+> **setAlt**(`alt`): [`BlobImageComponent`](#blobimagecomponent)
+
+###### Parameters
+
+| Parameter | Type |
+| --------- | ----- |
+| `alt` | `any` |
+
+###### Returns
+
+[`BlobImageComponent`](#blobimagecomponent)
+
+##### setCdnPrefix()
+
+> **setCdnPrefix**(`prefix`): [`BlobImageComponent`](#blobimagecomponent)
+
+###### Parameters
+
+| Parameter | Type |
+| --------- | ----- |
+| `prefix` | `any` |
+
+###### Returns
+
+[`BlobImageComponent`](#blobimagecomponent)
+
+##### setCid()
+
+> **setCid**(`cid`): [`BlobImageComponent`](#blobimagecomponent)
+
+###### Parameters
+
+| Parameter | Type |
+| --------- | ----- |
+| `cid` | `any` |
+
+###### Returns
+
+[`BlobImageComponent`](#blobimagecomponent)
+
+##### setDid()
+
+> **setDid**(`did`): [`BlobImageComponent`](#blobimagecomponent)
+
+###### Parameters
+
+| Parameter | Type |
+| --------- | ----- |
+| `did` | `any` |
+
+###### Returns
+
+[`BlobImageComponent`](#blobimagecomponent)
+
+---
+
+### ButtonComponent
+
+#### Properties
+
+| Property | Type |
+| ------------------------------- | ----- |
+| `el` | `any` |
+
+#### Methods
+
+##### onClick()
+
+> **onClick**(`callback`): [`ButtonComponent`](#buttoncomponent)
+
+###### Parameters
+
+| Parameter | Type |
+| ---------- | ----- |
+| `callback` | `any` |
+
+###### Returns
+
+[`ButtonComponent`](#buttoncomponent)
+
+##### setButtonText()
+
+> **setButtonText**(`text`): [`ButtonComponent`](#buttoncomponent)
+
+###### Parameters
+
+| Parameter | Type |
+| --------- | ----- |
+| `text` | `any` |
+
+###### Returns
+
+[`ButtonComponent`](#buttoncomponent)
+
+##### setCta()
+
+> **setCta**(): [`ButtonComponent`](#buttoncomponent)
+
+###### Returns
+
+[`ButtonComponent`](#buttoncomponent)
+
+---
+
+### Composer
+
+#### Constructors
+
+##### Constructor
+
+> **new Composer**(): [`Composer`](#composer)
+
+###### Returns
+
+[`Composer`](#composer)
+
+#### Methods
+
+##### appendText()
+
+> **appendText**(`text`): [`Composer`](#composer)
+
+###### Parameters
+
+| Parameter | Type |
+| --------- | ----- |
+| `text` | `any` |
+
+###### Returns
+
+[`Composer`](#composer)
+
+##### prependText()
+
+> **prependText**(`text`): [`Composer`](#composer)
+
+###### Parameters
+
+| Parameter | Type |
+| --------- | ----- |
+| `text` | `any` |
+
+###### Returns
+
+[`Composer`](#composer)
+
+##### setCursor()
+
+> **setCursor**(`index`): [`Composer`](#composer)
+
+###### Parameters
+
+| Parameter | Type |
+| --------- | ----- |
+| `index` | `any` |
+
+###### Returns
+
+[`Composer`](#composer)
+
+##### setText()
+
+> **setText**(`text`): [`Composer`](#composer)
+
+###### Parameters
+
+| Parameter | Type |
+| --------- | ----- |
+| `text` | `any` |
+
+###### Returns
+
+[`Composer`](#composer)
+
+---
+
+### DropdownComponent
+
+#### Properties
+
+| Property | Type |
+| ------------------------------- | ----- |
+| `el` | `any` |
+
+#### Methods
+
+##### addOption()
+
+> **addOption**(`value`, `label`): [`DropdownComponent`](#dropdowncomponent)
+
+###### Parameters
+
+| Parameter | Type |
+| --------- | ----- |
+| `value` | `any` |
+| `label` | `any` |
+
+###### Returns
+
+[`DropdownComponent`](#dropdowncomponent)
+
+##### addOptions()
+
+> **addOptions**(`map`): [`DropdownComponent`](#dropdowncomponent)
+
+###### Parameters
+
+| Parameter | Type |
+| --------- | ----- |
+| `map` | `any` |
+
+###### Returns
+
+[`DropdownComponent`](#dropdowncomponent)
+
+##### onChange()
+
+> **onChange**(`callback`): [`DropdownComponent`](#dropdowncomponent)
+
+###### Parameters
+
+| Parameter | Type |
+| ---------- | ----- |
+| `callback` | `any` |
+
+###### Returns
+
+[`DropdownComponent`](#dropdowncomponent)
+
+##### setValue()
+
+> **setValue**(`value`): [`DropdownComponent`](#dropdowncomponent)
+
+###### Parameters
+
+| Parameter | Type |
+| --------- | ----- |
+| `value` | `any` |
+
+###### Returns
+
+[`DropdownComponent`](#dropdowncomponent)
+
+---
+
+### FlattenedTokens
+
+#### Constructors
+
+##### Constructor
+
+> **new FlattenedTokens**(`tokens`): [`FlattenedTokens`](#flattenedtokens)
+
+###### Parameters
+
+| Parameter | Type |
+| --------- | ----- |
+| `tokens` | `any` |
+
+###### Returns
+
+[`FlattenedTokens`](#flattenedtokens)
+
+#### Properties
+
+| Property | Type |
+| --------------------------------- | -------- |
+| `text` | `string` |
+
+#### Methods
+
+##### textFor()
+
+> **textFor**(`start`, `end`): `string`
+
+###### Parameters
+
+| Parameter | Type |
+| --------- | ----- |
+| `start` | `any` |
+| `end` | `any` |
+
+###### Returns
+
+`string`
+
+##### tokensFor()
+
+> **tokensFor**(`start`, `end`): `any`[]
+
+###### Parameters
+
+| Parameter | Type |
+| --------- | ----- |
+| `start` | `any` |
+| `end` | `any` |
+
+###### Returns
+
+`any`[]
+
+---
+
+### IconComponent
+
+#### Properties
+
+| Property | Type |
+| ------------------------------- | ----- |
+| `el` | `any` |
+
+#### Methods
+
+##### setIcon()
+
+> **setIcon**(`name`): [`IconComponent`](#iconcomponent)
+
+###### Parameters
+
+| Parameter | Type |
+| --------- | ----- |
+| `name` | `any` |
+
+###### Returns
+
+[`IconComponent`](#iconcomponent)
+
+---
+
+### Menu
+
+#### Constructors
+
+##### Constructor
+
+> **new Menu**(): [`Menu`](#menu)
+
+###### Returns
+
+[`Menu`](#menu)
+
+#### Properties
+
+| Property | Type |
+| ----------------------------------- | ------- |
+| `items` | `any`[] |
+
+#### Methods
+
+##### addItem()
+
+> **addItem**(`builder`): [`Menu`](#menu)
+
+###### Parameters
+
+| Parameter | Type |
+| --------- | ----- |
+| `builder` | `any` |
+
+###### Returns
+
+[`Menu`](#menu)
+
+---
+
+### MenuItem
+
+#### Constructors
+
+##### Constructor
+
+> **new MenuItem**(): [`MenuItem`](#menuitem)
+
+###### Returns
+
+[`MenuItem`](#menuitem)
+
+#### Properties
+
+| Property | Type |
+| ----------------------------------- | -------- |
+| `icon` | `any` |
+| `title` | `string` |
+
+#### Methods
+
+##### onClick()
+
+> **onClick**(`callback`): [`MenuItem`](#menuitem)
+
+###### Parameters
+
+| Parameter | Type |
+| ---------- | ----- |
+| `callback` | `any` |
+
+###### Returns
+
+[`MenuItem`](#menuitem)
+
+##### setIcon()
+
+> **setIcon**(`icon`): [`MenuItem`](#menuitem)
+
+###### Parameters
+
+| Parameter | Type |
+| --------- | ----- |
+| `icon` | `any` |
+
+###### Returns
+
+[`MenuItem`](#menuitem)
+
+##### setTitle()
+
+> **setTitle**(`title`): [`MenuItem`](#menuitem)
+
+###### Parameters
+
+| Parameter | Type |
+| --------- | ----- |
+| `title` | `any` |
+
+###### Returns
+
+[`MenuItem`](#menuitem)
+
+---
+
+### Modal
+
+#### Constructors
+
+##### Constructor
+
+> **new Modal**(): [`Modal`](#modal)
+
+###### Returns
+
+[`Modal`](#modal)
+
+#### Properties
+
+| Property | Type |
+| ------------------------------------------- | ------------------------- |
+| `contentEl` | [`VirtualEl`](#virtualel) |
+| `titleEl` | [`VirtualEl`](#virtualel) |
+
+#### Methods
+
+##### close()
+
+> **close**(): `void`
+
+###### Returns
+
+`void`
+
+##### onClose()
+
+> **onClose**(): `void`
+
+###### Returns
+
+`void`
+
+##### onOpen()
+
+> **onOpen**(): `void`
+
+###### Returns
+
+`void`
+
+##### open()
+
+> **open**(): `void`
+
+###### Returns
+
+`void`
+
+##### update()
+
+> **update**(): `void`
+
+###### Returns
+
+`void`
+
+---
+
+### Notice
+
+#### Constructors
+
+##### Constructor
+
+> **new Notice**(`message`, `timeout?`): [`Notice`](#notice)
+
+###### Parameters
+
+| Parameter | Type | Default value |
+| --------- | -------- | ------------- |
+| `message` | `any` | `undefined` |
+| `timeout` | `number` | `0` |
+
+###### Returns
+
+[`Notice`](#notice)
+
+#### Properties
+
+| Property | Type |
+| ----------------------------------------- | ------------------------- |
+| `noticeEl` | [`VirtualEl`](#virtualel) |
+
+#### Methods
+
+##### hide()
+
+> **hide**(): `void`
+
+###### Returns
+
+`void`
+
+##### setMessage()
+
+> **setMessage**(`message`): [`Notice`](#notice)
+
+###### Parameters
+
+| Parameter | Type |
+| --------- | ----- |
+| `message` | `any` |
+
+###### Returns
+
+[`Notice`](#notice)
+
+---
+
+### Plugin
+
+#### Constructors
+
+##### Constructor
+
+> **new Plugin**(): [`Plugin`](#plugin)
+
+###### Returns
+
+[`Plugin`](#plugin)
+
+#### Properties
+
+| Property | Type |
+| ------------------------------- | ------------- |
+| `app` | [`App`](#app) |
+
+#### Methods
+
+##### addFeedFilter()
+
+> **addFeedFilter**(`callback?`): `void`
+
+###### Parameters
+
+| Parameter | Type |
+| ---------- | ------------ |
+| `callback` | () => `void` |
+
+###### Returns
+
+`void`
+
+##### addSettingTab()
+
+> **addSettingTab**(`tab`): `void`
+
+###### Parameters
+
+| Parameter | Type |
+| --------- | ----- |
+| `tab` | `any` |
+
+###### Returns
+
+`void`
+
+##### addSidebarItem()
+
+> **addSidebarItem**(`icon`, `title`, `callback?`): `void`
+
+###### Parameters
+
+| Parameter | Type |
+| ---------- | ------------ |
+| `icon` | `any` |
+| `title` | `any` |
+| `callback` | () => `void` |
+
+###### Returns
+
+`void`
+
+##### loadData()
+
+> **loadData**(): `Promise`\<`any`\>
+
+###### Returns
+
+`Promise`\<`any`\>
+
+##### loadLocalData()
+
+> **loadLocalData**(): `Promise`\<`any`\>
+
+###### Returns
+
+`Promise`\<`any`\>
+
+##### onload()
+
+> **onload**(): `void`
+
+###### Returns
+
+`void`
+
+##### onunload()
+
+> **onunload**(): `void`
+
+###### Returns
+
+`void`
+
+##### openPage()
+
+> **openPage**(`pageId`): `Promise`\<`any`\>
+
+###### Parameters
+
+| Parameter | Type |
+| --------- | ----- |
+| `pageId` | `any` |
+
+###### Returns
+
+`Promise`\<`any`\>
+
+##### refreshPage()
+
+> **refreshPage**(`pageId`, `__namedParameters?`): `Promise`\<`any`\>
+
+###### Parameters
+
+| Parameter | Type |
+| -------------------------- | -------------------------- |
+| `pageId` | `any` |
+| `__namedParameters` | \{ `reset?`: `boolean`; \} |
+| `__namedParameters.reset?` | `boolean` |
+
+###### Returns
+
+`Promise`\<`any`\>
+
+##### refreshSlot()
+
+> **refreshSlot**(`name`, `options?`): `Promise`\<`any`\>
+
+###### Parameters
+
+| Parameter | Type |
+| --------- | ----- |
+| `name` | `any` |
+| `options` | \{ \} |
+
+###### Returns
+
+`Promise`\<`any`\>
+
+##### registerPage()
+
+> **registerPage**(`__namedParameters`): `void`
+
+###### Parameters
+
+| Parameter | Type |
+| ---------------------------- | ------------------------------------------------------------ |
+| `__namedParameters` | \{ `display?`: () => `any`; `id`: `any`; `title?`: `any`; \} |
+| `__namedParameters.display?` | () => `any` |
+| `__namedParameters.id` | `any` |
+| `__namedParameters.title?` | `any` |
+
+###### Returns
+
+`void`
+
+##### registerRichTextTransform()
+
+> **registerRichTextTransform**(`callback?`, `options?`): `void`
+
+###### Parameters
+
+| Parameter | Type |
+| ---------- | ------------------- |
+| `callback` | (`tokens`) => `any` |
+| `options` | \{ \} |
+
+###### Returns
+
+`void`
+
+##### registerSlot()
+
+> **registerSlot**(`name`, `callback?`, `options?`): `void`
+
+###### Parameters
+
+| Parameter | Type |
+| ---------- | ----------- |
+| `name` | `any` |
+| `callback` | () => `any` |
+| `options` | \{ \} |
+
+###### Returns
+
+`void`
+
+##### saveData()
+
+> **saveData**(`data`): `Promise`\<`void`\>
+
+###### Parameters
+
+| Parameter | Type |
+| --------- | ----- |
+| `data` | `any` |
+
+###### Returns
+
+`Promise`\<`void`\>
+
+##### saveLocalData()
+
+> **saveLocalData**(`data`): `Promise`\<`void`\>
+
+###### Parameters
+
+| Parameter | Type |
+| --------- | ----- |
+| `data` | `any` |
+
+###### Returns
+
+`Promise`\<`void`\>
+
+##### register()
+
+> `static` **register**(): `void`
+
+###### Returns
+
+`void`
+
+---
+
+### PluginData
+
+#### Constructors
+
+##### Constructor
+
+> **new PluginData**(): [`PluginData`](#plugindata)
+
+###### Returns
+
+[`PluginData`](#plugindata)
+
+#### Methods
+
+##### getDetailedProfile()
+
+> **getDetailedProfile**(`did`): `Promise`\<`any`\>
+
+###### Parameters
+
+| Parameter | Type |
+| --------- | ----- |
+| `did` | `any` |
+
+###### Returns
+
+`Promise`\<`any`\>
+
+##### getKnownFollowers()
+
+> **getKnownFollowers**(`did`): `Promise`\<`any`\>
+
+###### Parameters
+
+| Parameter | Type |
+| --------- | ----- |
+| `did` | `any` |
+
+###### Returns
+
+`Promise`\<`any`\>
+
+##### getPost()
+
+> **getPost**(`uri`): `Promise`\<`any`\>
+
+###### Parameters
+
+| Parameter | Type |
+| --------- | ----- |
+| `uri` | `any` |
+
+###### Returns
+
+`Promise`\<`any`\>
+
+##### getProfile()
+
+> **getProfile**(`did`): `Promise`\<`any`\>
+
+###### Parameters
+
+| Parameter | Type |
+| --------- | ----- |
+| `did` | `any` |
+
+###### Returns
+
+`Promise`\<`any`\>
+
+##### getRecord()
+
+> **getRecord**(`repo`, `collection`, `rkey`): `Promise`\<`any`\>
+
+###### Parameters
+
+| Parameter | Type |
+| ------------ | ----- |
+| `repo` | `any` |
+| `collection` | `any` |
+| `rkey` | `any` |
+
+###### Returns
+
+`Promise`\<`any`\>
+
+---
+
+### PluginResponse
+
+#### Properties
+
+| Property | Type |
+| --------------------------------------- | ------------------------ |
+| `headers` | `Map`\<`string`, `any`\> |
+| `ok` | `any` |
+| `status` | `any` |
+
+#### Methods
+
+##### json()
+
+> **json**(): `Promise`\<`any`\>
+
+###### Returns
+
+`Promise`\<`any`\>
+
+##### text()
+
+> **text**(): `Promise`\<`any`\>
+
+###### Returns
+
+`Promise`\<`any`\>
+
+---
+
+### PluginSettingTab
+
+#### Constructors
+
+##### Constructor
+
+> **new PluginSettingTab**(): [`PluginSettingTab`](#pluginsettingtab)
+
+###### Returns
+
+[`PluginSettingTab`](#pluginsettingtab)
+
+#### Properties
+
+| Property | Type |
+| ----------------------------------------------- | ------------------------- |
+| `containerEl` | [`VirtualEl`](#virtualel) |
+| `name` | `any` |
+
+#### Methods
+
+##### display()
+
+> **display**(): `void`
+
+###### Returns
+
+`void`
+
+##### refresh()
+
+> **refresh**(`__namedParameters?`): `Promise`\<`any`\>
+
+###### Parameters
+
+| Parameter | Type |
+| -------------------------- | -------------------------- |
+| `__namedParameters` | \{ `reset?`: `boolean`; \} |
+| `__namedParameters.reset?` | `boolean` |
+
+###### Returns
+
+`Promise`\<`any`\>
+
+##### setName()
+
+> **setName**(`name`): [`PluginSettingTab`](#pluginsettingtab)
+
+###### Parameters
+
+| Parameter | Type |
+| --------- | ----- |
+| `name` | `any` |
+
+###### Returns
+
+[`PluginSettingTab`](#pluginsettingtab)
+
+---
+
+### PostsFeedComponent
+
+#### Properties
+
+| Property | Type |
+| ------------------------------- | ----- |
+| `el` | `any` |
+
+#### Methods
+
+##### setEmptyMessage()
+
+> **setEmptyMessage**(`message`): [`PostsFeedComponent`](#postsfeedcomponent)
+
+###### Parameters
+
+| Parameter | Type |
+| --------- | ----- |
+| `message` | `any` |
+
+###### Returns
+
+[`PostsFeedComponent`](#postsfeedcomponent)
+
+##### setUris()
+
+> **setUris**(`uris`): [`PostsFeedComponent`](#postsfeedcomponent)
+
+###### Parameters
+
+| Parameter | Type |
+| --------- | ----- |
+| `uris` | `any` |
+
+###### Returns
+
+[`PostsFeedComponent`](#postsfeedcomponent)
+
+---
+
+### ProfilesListComponent
+
+#### Properties
+
+| Property | Type |
+| ------------------------------- | ----- |
+| `el` | `any` |
+
+#### Methods
+
+##### setDids()
+
+> **setDids**(`dids`): [`ProfilesListComponent`](#profileslistcomponent)
+
+###### Parameters
+
+| Parameter | Type |
+| --------- | ----- |
+| `dids` | `any` |
+
+###### Returns
+
+[`ProfilesListComponent`](#profileslistcomponent)
+
+##### setEmptyMessage()
+
+> **setEmptyMessage**(`message`): [`ProfilesListComponent`](#profileslistcomponent)
+
+###### Parameters
+
+| Parameter | Type |
+| --------- | ----- |
+| `message` | `any` |
+
+###### Returns
+
+[`ProfilesListComponent`](#profileslistcomponent)
+
+---
+
+### Setting
+
+#### Constructors
+
+##### Constructor
+
+> **new Setting**(`containerEl`): [`Setting`](#setting)
+
+###### Parameters
+
+| Parameter | Type |
+| ------------- | ----- |
+| `containerEl` | `any` |
+
+###### Returns
+
+[`Setting`](#setting)
+
+#### Properties
+
+| Property | Type |
+| ------------------------------------------- | ----- |
+| `controlEl` | `any` |
+| `descEl` | `any` |
+| `infoEl` | `any` |
+| `nameEl` | `any` |
+| `settingEl` | `any` |
+
+#### Methods
+
+##### addButton()
+
+> **addButton**(`callback`): [`Setting`](#setting)
+
+###### Parameters
+
+| Parameter | Type |
+| ---------- | ----- |
+| `callback` | `any` |
+
+###### Returns
+
+[`Setting`](#setting)
+
+##### addDropdown()
+
+> **addDropdown**(`callback`): [`Setting`](#setting)
+
+###### Parameters
+
+| Parameter | Type |
+| ---------- | ----- |
+| `callback` | `any` |
+
+###### Returns
+
+[`Setting`](#setting)
+
+##### addText()
+
+> **addText**(`callback`): [`Setting`](#setting)
+
+###### Parameters
+
+| Parameter | Type |
+| ---------- | ----- |
+| `callback` | `any` |
+
+###### Returns
+
+[`Setting`](#setting)
+
+##### addTextArea()
+
+> **addTextArea**(`callback`): [`Setting`](#setting)
+
+###### Parameters
+
+| Parameter | Type |
+| ---------- | ----- |
+| `callback` | `any` |
+
+###### Returns
+
+[`Setting`](#setting)
+
+##### addToggle()
+
+> **addToggle**(`callback`): [`Setting`](#setting)
+
+###### Parameters
+
+| Parameter | Type |
+| ---------- | ----- |
+| `callback` | `any` |
+
+###### Returns
+
+[`Setting`](#setting)
+
+##### setDesc()
+
+> **setDesc**(`text`): [`Setting`](#setting)
+
+###### Parameters
+
+| Parameter | Type |
+| --------- | ----- |
+| `text` | `any` |
+
+###### Returns
+
+[`Setting`](#setting)
+
+##### setName()
+
+> **setName**(`text`): [`Setting`](#setting)
+
+###### Parameters
+
+| Parameter | Type |
+| --------- | ----- |
+| `text` | `any` |
+
+###### Returns
+
+[`Setting`](#setting)
+
+---
+
+### SimpleUUID
+
+#### Constructors
+
+##### Constructor
+
+> **new SimpleUUID**(): [`SimpleUUID`](#simpleuuid)
+
+###### Returns
+
+[`SimpleUUID`](#simpleuuid)
+
+#### Methods
+
+##### create()
+
+> **create**(): `number`
+
+###### Returns
+
+`number`
+
+---
+
+### StyleSnippet
+
+#### Constructors
+
+##### Constructor
+
+> **new StyleSnippet**(`cssText`): [`StyleSnippet`](#stylesnippet)
+
+###### Parameters
+
+| Parameter | Type |
+| --------- | ----- |
+| `cssText` | `any` |
+
+###### Returns
+
+[`StyleSnippet`](#stylesnippet)
+
+#### Properties
+
+| Property | Type |
+| ----------------------------------- | ------------------ |
+| `ready` | `Promise`\<`any`\> |
+
+#### Methods
+
+##### remove()
+
+> **remove**(): `void`
+
+###### Returns
+
+`void`
+
+---
+
+### TextAreaComponent
+
+#### Properties
+
+| Property | Type |
+| ------------------------------- | ----- |
+| `el` | `any` |
+
+#### Methods
+
+##### onChange()
+
+> **onChange**(`callback`): [`TextAreaComponent`](#textareacomponent)
+
+###### Parameters
+
+| Parameter | Type |
+| ---------- | ----- |
+| `callback` | `any` |
+
+###### Returns
+
+[`TextAreaComponent`](#textareacomponent)
+
+##### setPlaceholder()
+
+> **setPlaceholder**(`value`): [`TextAreaComponent`](#textareacomponent)
+
+###### Parameters
+
+| Parameter | Type |
+| --------- | ----- |
+| `value` | `any` |
+
+###### Returns
+
+[`TextAreaComponent`](#textareacomponent)
+
+##### setValue()
+
+> **setValue**(`value`): [`TextAreaComponent`](#textareacomponent)
+
+###### Parameters
+
+| Parameter | Type |
+| --------- | ----- |
+| `value` | `any` |
+
+###### Returns
+
+[`TextAreaComponent`](#textareacomponent)
+
+---
+
+### TextComponent
+
+#### Properties
+
+| Property | Type |
+| ------------------------------- | ----- |
+| `el` | `any` |
+
+#### Methods
+
+##### onChange()
+
+> **onChange**(`callback`): [`TextComponent`](#textcomponent)
+
+###### Parameters
+
+| Parameter | Type |
+| ---------- | ----- |
+| `callback` | `any` |
+
+###### Returns
+
+[`TextComponent`](#textcomponent)
+
+##### setPlaceholder()
+
+> **setPlaceholder**(`value`): [`TextComponent`](#textcomponent)
+
+###### Parameters
+
+| Parameter | Type |
+| --------- | ----- |
+| `value` | `any` |
+
+###### Returns
+
+[`TextComponent`](#textcomponent)
+
+##### setValue()
+
+> **setValue**(`value`): [`TextComponent`](#textcomponent)
+
+###### Parameters
+
+| Parameter | Type |
+| --------- | ----- |
+| `value` | `any` |
+
+###### Returns
+
+[`TextComponent`](#textcomponent)
+
+---
+
+### ToggleComponent
+
+#### Properties
+
+| Property | Type |
+| ------------------------------- | ----- |
+| `el` | `any` |
+
+#### Methods
+
+##### onChange()
+
+> **onChange**(`callback`): [`ToggleComponent`](#togglecomponent)
+
+###### Parameters
+
+| Parameter | Type |
+| ---------- | ----- |
+| `callback` | `any` |
+
+###### Returns
+
+[`ToggleComponent`](#togglecomponent)
+
+##### setValue()
+
+> **setValue**(`value`): [`ToggleComponent`](#togglecomponent)
+
+###### Parameters
+
+| Parameter | Type |
+| --------- | ----- |
+| `value` | `any` |
+
+###### Returns
+
+[`ToggleComponent`](#togglecomponent)
+
+---
+
+### VirtualEl
+
+#### Constructors
+
+##### Constructor
+
+> **new VirtualEl**(`tag`): [`VirtualEl`](#virtualel)
+
+###### Parameters
+
+| Parameter | Type |
+| --------- | ----- |
+| `tag` | `any` |
+
+###### Returns
+
+[`VirtualEl`](#virtualel)
+
+#### Properties
+
+| Property | Type |
+| ----------------------------------------- | -------- |
+| `attrs` | `object` |
+| `children` | `any`[] |
+| `events` | `object` |
+| `styles` | `object` |
+| `tag` | `any` |
+
+#### Methods
+
+##### addClass()
+
+> **addClass**(`cls`): [`VirtualEl`](#virtualel)
+
+###### Parameters
+
+| Parameter | Type |
+| --------- | ----- |
+| `cls` | `any` |
+
+###### Returns
+
+[`VirtualEl`](#virtualel)
+
+##### appendChild()
+
+> **appendChild**(`child`): [`VirtualEl`](#virtualel)
+
+###### Parameters
+
+| Parameter | Type |
+| --------- | ----- |
+| `child` | `any` |
+
+###### Returns
+
+[`VirtualEl`](#virtualel)
+
+##### appendText()
+
+> **appendText**(`value`): [`VirtualEl`](#virtualel)
+
+###### Parameters
+
+| Parameter | Type |
+| --------- | ----- |
+| `value` | `any` |
+
+###### Returns
+
+[`VirtualEl`](#virtualel)
+
+##### createBlobImage()
+
+> **createBlobImage**(`callback`): [`BlobImageComponent`](#blobimagecomponent)
+
+###### Parameters
+
+| Parameter | Type |
+| ---------- | ----- |
+| `callback` | `any` |
+
+###### Returns
+
+[`BlobImageComponent`](#blobimagecomponent)
+
+##### createDiv()
+
+> **createDiv**(`options?`, `callback`): [`VirtualEl`](#virtualel)
+
+###### Parameters
+
+| Parameter | Type |
+| ---------- | ----- |
+| `options` | \{ \} |
+| `callback` | `any` |
+
+###### Returns
+
+[`VirtualEl`](#virtualel)
+
+##### createEl()
+
+> **createEl**(`tag`, `options?`, `callback`): [`VirtualEl`](#virtualel)
+
+###### Parameters
+
+| Parameter | Type |
+| ---------- | ----- |
+| `tag` | `any` |
+| `options` | \{ \} |
+| `callback` | `any` |
+
+###### Returns
+
+[`VirtualEl`](#virtualel)
+
+##### createIcon()
+
+> **createIcon**(`callback`): [`IconComponent`](#iconcomponent)
+
+###### Parameters
+
+| Parameter | Type |
+| ---------- | ----- |
+| `callback` | `any` |
+
+###### Returns
+
+[`IconComponent`](#iconcomponent)
+
+##### createPostsFeed()
+
+> **createPostsFeed**(`callback`): [`PostsFeedComponent`](#postsfeedcomponent)
+
+###### Parameters
+
+| Parameter | Type |
+| ---------- | ----- |
+| `callback` | `any` |
+
+###### Returns
+
+[`PostsFeedComponent`](#postsfeedcomponent)
+
+##### createProfilesList()
+
+> **createProfilesList**(`callback`): [`ProfilesListComponent`](#profileslistcomponent)
+
+###### Parameters
+
+| Parameter | Type |
+| ---------- | ----- |
+| `callback` | `any` |
+
+###### Returns
+
+[`ProfilesListComponent`](#profileslistcomponent)
+
+##### createSpan()
+
+> **createSpan**(`options?`, `callback`): [`VirtualEl`](#virtualel)
+
+###### Parameters
+
+| Parameter | Type |
+| ---------- | ----- |
+| `options` | \{ \} |
+| `callback` | `any` |
+
+###### Returns
+
+[`VirtualEl`](#virtualel)
+
+##### createText()
+
+> **createText**(`value`): [`VirtualText`](#virtualtext)
+
+###### Parameters
+
+| Parameter | Type |
+| --------- | ----- |
+| `value` | `any` |
+
+###### Returns
+
+[`VirtualText`](#virtualtext)
+
+##### empty()
+
+> **empty**(): [`VirtualEl`](#virtualel)
+
+###### Returns
+
+[`VirtualEl`](#virtualel)
+
+##### onChange()
+
+> **onChange**(`fn`): [`VirtualEl`](#virtualel)
+
+###### Parameters
+
+| Parameter | Type |
+| --------- | ----- |
+| `fn` | `any` |
+
+###### Returns
+
+[`VirtualEl`](#virtualel)
+
+##### onClick()
+
+> **onClick**(`fn`): [`VirtualEl`](#virtualel)
+
+###### Parameters
+
+| Parameter | Type |
+| --------- | ----- |
+| `fn` | `any` |
+
+###### Returns
+
+[`VirtualEl`](#virtualel)
+
+##### onInput()
+
+> **onInput**(`fn`): [`VirtualEl`](#virtualel)
+
+###### Parameters
+
+| Parameter | Type |
+| --------- | ----- |
+| `fn` | `any` |
+
+###### Returns
+
+[`VirtualEl`](#virtualel)
+
+##### setAttr()
+
+> **setAttr**(`name`, `value`): [`VirtualEl`](#virtualel)
+
+###### Parameters
+
+| Parameter | Type |
+| --------- | ----- |
+| `name` | `any` |
+| `value` | `any` |
+
+###### Returns
+
+[`VirtualEl`](#virtualel)
+
+##### setStyle()
+
+> **setStyle**(`name`, `value`): [`VirtualEl`](#virtualel)
+
+###### Parameters
+
+| Parameter | Type |
+| --------- | ----- |
+| `name` | `any` |
+| `value` | `any` |
+
+###### Returns
+
+[`VirtualEl`](#virtualel)
+
+##### setText()
+
+> **setText**(`text`): [`VirtualEl`](#virtualel)
+
+###### Parameters
+
+| Parameter | Type |
+| --------- | ----- |
+| `text` | `any` |
+
+###### Returns
+
+[`VirtualEl`](#virtualel)
+
+---
+
+### VirtualText
+
+#### Constructors
+
+##### Constructor
+
+> **new VirtualText**(`value`): [`VirtualText`](#virtualtext)
+
+###### Parameters
+
+| Parameter | Type |
+| --------- | ----- |
+| `value` | `any` |
+
+###### Returns
+
+[`VirtualText`](#virtualtext)
+
+#### Properties
+
+| Property | Type |
+| ----------------------------------- | -------- |
+| `value` | `string` |
+
+## Functions
+
+### fetch()
+
+> **fetch**(`url`, `init?`): `Promise`\<[`PluginResponse`](#pluginresponse)\>
+
+#### Parameters
+
+| Parameter | Type |
+| --------- | ----- |
+| `url` | `any` |
+| `init` | \{ \} |
+
+#### Returns
+
+`Promise`\<[`PluginResponse`](#pluginresponse)\>
+
+---
+
+### flattenForScan()
+
+> **flattenForScan**(`tokens`): [`FlattenedTokens`](#flattenedtokens)
+
+#### Parameters
+
+| Parameter | Type |
+| --------- | ----- |
+| `tokens` | `any` |
+
+#### Returns
+
+[`FlattenedTokens`](#flattenedtokens)
diff --git a/impro-plugin/package-lock.json b/impro-plugin/package-lock.json
deleted file mode 100644
index c72b4d96..00000000
--- a/impro-plugin/package-lock.json
+++ /dev/null
@@ -1,289 +0,0 @@
-{
- "name": "@impro.social/impro-plugin",
- "version": "0.0.20",
- "lockfileVersion": 3,
- "requires": true,
- "packages": {
- "": {
- "name": "@impro.social/impro-plugin",
- "version": "0.0.20",
- "license": "0BSD",
- "devDependencies": {
- "typedoc": "^0.28.20"
- }
- },
- "node_modules/@gerrit0/mini-shiki": {
- "version": "3.23.0",
- "resolved": "https://registry.npmjs.org/@gerrit0/mini-shiki/-/mini-shiki-3.23.0.tgz",
- "integrity": "sha512-bEMORlG0cqdjVyCEuU0cDQbORWX+kYCeo0kV1lbxF5bt4r7SID2l9bqsxJEM0zndaxpOUT7riCyIVEuqq/Ynxg==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@shikijs/engine-oniguruma": "^3.23.0",
- "@shikijs/langs": "^3.23.0",
- "@shikijs/themes": "^3.23.0",
- "@shikijs/types": "^3.23.0",
- "@shikijs/vscode-textmate": "^10.0.2"
- }
- },
- "node_modules/@shikijs/engine-oniguruma": {
- "version": "3.23.0",
- "resolved": "https://registry.npmjs.org/@shikijs/engine-oniguruma/-/engine-oniguruma-3.23.0.tgz",
- "integrity": "sha512-1nWINwKXxKKLqPibT5f4pAFLej9oZzQTsby8942OTlsJzOBZ0MWKiwzMsd+jhzu8YPCHAswGnnN1YtQfirL35g==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@shikijs/types": "3.23.0",
- "@shikijs/vscode-textmate": "^10.0.2"
- }
- },
- "node_modules/@shikijs/langs": {
- "version": "3.23.0",
- "resolved": "https://registry.npmjs.org/@shikijs/langs/-/langs-3.23.0.tgz",
- "integrity": "sha512-2Ep4W3Re5aB1/62RSYQInK9mM3HsLeB91cHqznAJMuylqjzNVAVCMnNWRHFtcNHXsoNRayP9z1qj4Sq3nMqYXg==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@shikijs/types": "3.23.0"
- }
- },
- "node_modules/@shikijs/themes": {
- "version": "3.23.0",
- "resolved": "https://registry.npmjs.org/@shikijs/themes/-/themes-3.23.0.tgz",
- "integrity": "sha512-5qySYa1ZgAT18HR/ypENL9cUSGOeI2x+4IvYJu4JgVJdizn6kG4ia5Q1jDEOi7gTbN4RbuYtmHh0W3eccOrjMA==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@shikijs/types": "3.23.0"
- }
- },
- "node_modules/@shikijs/types": {
- "version": "3.23.0",
- "resolved": "https://registry.npmjs.org/@shikijs/types/-/types-3.23.0.tgz",
- "integrity": "sha512-3JZ5HXOZfYjsYSk0yPwBrkupyYSLpAE26Qc0HLghhZNGTZg/SKxXIIgoxOpmmeQP0RRSDJTk1/vPfw9tbw+jSQ==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@shikijs/vscode-textmate": "^10.0.2",
- "@types/hast": "^3.0.4"
- }
- },
- "node_modules/@shikijs/vscode-textmate": {
- "version": "10.0.2",
- "resolved": "https://registry.npmjs.org/@shikijs/vscode-textmate/-/vscode-textmate-10.0.2.tgz",
- "integrity": "sha512-83yeghZ2xxin3Nj8z1NMd/NCuca+gsYXswywDy5bHvwlWL8tpTQmzGeUuHd9FC3E/SBEMvzJRwWEOz5gGes9Qg==",
- "dev": true,
- "license": "MIT"
- },
- "node_modules/@types/hast": {
- "version": "3.0.5",
- "resolved": "https://registry.npmjs.org/@types/hast/-/hast-3.0.5.tgz",
- "integrity": "sha512-rp/ezSWaD1m44dPKICGhiskI13nVr7qTloFwDa/IYkhhf5nzwP+zIQcIJh3WIFSBOy/H1PzB40jPjMDksN4F+g==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@types/unist": "*"
- }
- },
- "node_modules/@types/unist": {
- "version": "3.0.3",
- "resolved": "https://registry.npmjs.org/@types/unist/-/unist-3.0.3.tgz",
- "integrity": "sha512-ko/gIFJRv177XgZsZcBwnqJN5x/Gien8qNOn0D5bQU/zAzVf9Zt3BlcUiLqhV9y4ARk0GbT3tnUiPNgnTXzc/Q==",
- "dev": true,
- "license": "MIT"
- },
- "node_modules/argparse": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz",
- "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==",
- "dev": true,
- "license": "Python-2.0"
- },
- "node_modules/balanced-match": {
- "version": "4.0.4",
- "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-4.0.4.tgz",
- "integrity": "sha512-BLrgEcRTwX2o6gGxGOCNyMvGSp35YofuYzw9h1IMTRmKqttAZZVU67bdb9Pr2vUHA8+j3i2tJfjO6C6+4myGTA==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": "18 || 20 || >=22"
- }
- },
- "node_modules/brace-expansion": {
- "version": "5.0.9",
- "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.9.tgz",
- "integrity": "sha512-ScQ4IuvIEF1TMlP7Zt+vjJ//9zlPb2SDcxWxM3bk8s6t6GGdJ7KO1dCcTidOPJKePW30LE/2cT7wCyPho9/Wxg==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "balanced-match": "^4.0.2"
- },
- "engines": {
- "node": "20 || >=22"
- }
- },
- "node_modules/entities": {
- "version": "4.5.0",
- "resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz",
- "integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==",
- "dev": true,
- "license": "BSD-2-Clause",
- "engines": {
- "node": ">=0.12"
- },
- "funding": {
- "url": "https://github.com/fb55/entities?sponsor=1"
- }
- },
- "node_modules/linkify-it": {
- "version": "5.0.2",
- "resolved": "https://registry.npmjs.org/linkify-it/-/linkify-it-5.0.2.tgz",
- "integrity": "sha512-ONTm2jCMAVZjgQa/Fy1kScXsuOoF5NPTsoFBdE1KVIZ2vAh/r9+Bqo+0jINCBYnavTPQZz38QzFTme79ENoN3Q==",
- "dev": true,
- "funding": [
- {
- "type": "github",
- "url": "https://github.com/sponsors/puzrin"
- },
- {
- "type": "github",
- "url": "https://github.com/sponsors/markdown-it"
- }
- ],
- "license": "MIT",
- "dependencies": {
- "uc.micro": "^2.0.0"
- }
- },
- "node_modules/lunr": {
- "version": "2.3.9",
- "resolved": "https://registry.npmjs.org/lunr/-/lunr-2.3.9.tgz",
- "integrity": "sha512-zTU3DaZaF3Rt9rhN3uBMGQD3dD2/vFQqnvZCDv4dl5iOzq2IZQqTxu90r4E5J+nP70J3ilqVCrbho2eWaeW8Ow==",
- "dev": true,
- "license": "MIT"
- },
- "node_modules/markdown-it": {
- "version": "14.3.0",
- "resolved": "https://registry.npmjs.org/markdown-it/-/markdown-it-14.3.0.tgz",
- "integrity": "sha512-RCEsPjR+sr0x+AuYp601tKTkgFG4YEPLCzHST3cQ/fhlJkqAkz1L2/Qbp1j9qw5SBwQHFBoW8+hoN5xssOF0Tw==",
- "dev": true,
- "funding": [
- {
- "type": "github",
- "url": "https://github.com/sponsors/puzrin"
- },
- {
- "type": "github",
- "url": "https://github.com/sponsors/markdown-it"
- }
- ],
- "license": "MIT",
- "dependencies": {
- "argparse": "^2.0.1",
- "entities": "^4.5.0",
- "linkify-it": "^5.0.2",
- "mdurl": "^2.0.0",
- "punycode.js": "^2.3.1",
- "uc.micro": "^2.1.0"
- },
- "bin": {
- "markdown-it": "bin/markdown-it.mjs"
- }
- },
- "node_modules/mdurl": {
- "version": "2.1.0",
- "resolved": "https://registry.npmjs.org/mdurl/-/mdurl-2.1.0.tgz",
- "integrity": "sha512-1+HBaOx0zi/dQWht8rNv9MYf9qqpqL/kxI0hXImU6Y547zM6Sni8BQibt7ifgMcYtQg41ao3Ivd6cnSM86inpg==",
- "dev": true,
- "license": "MIT"
- },
- "node_modules/minimatch": {
- "version": "10.2.6",
- "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.2.6.tgz",
- "integrity": "sha512-vpLQEs+VLCr1nU0BXS07maYoFwlDAH0gngQuuttxIwutDFEMHq2blX+8vpgxDdK3J1PwjCJiep77OitTZ4Ll1A==",
- "dev": true,
- "license": "BlueOak-1.0.0",
- "dependencies": {
- "brace-expansion": "^5.0.8"
- },
- "engines": {
- "node": "18 || 20 || >=22"
- },
- "funding": {
- "url": "https://github.com/sponsors/isaacs"
- }
- },
- "node_modules/punycode.js": {
- "version": "2.3.1",
- "resolved": "https://registry.npmjs.org/punycode.js/-/punycode.js-2.3.1.tgz",
- "integrity": "sha512-uxFIHU0YlHYhDQtV4R9J6a52SLx28BCjT+4ieh7IGbgwVJWO+km431c4yRlREUAsAmt/uMjQUyQHNEPf0M39CA==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=6"
- }
- },
- "node_modules/typedoc": {
- "version": "0.28.20",
- "resolved": "https://registry.npmjs.org/typedoc/-/typedoc-0.28.20.tgz",
- "integrity": "sha512-uSKqkh8Cr48vllnEy+jdaAgOeR6Y+QCBW7usgUsKj7gJEfR7stw9U/fE49LBnj2tPRKPY0c0EBJSWe9Appmplg==",
- "dev": true,
- "license": "Apache-2.0",
- "dependencies": {
- "@gerrit0/mini-shiki": "^3.23.0",
- "lunr": "^2.3.9",
- "markdown-it": "^14.3.0",
- "minimatch": "^10.2.5",
- "yaml": "^2.9.0"
- },
- "bin": {
- "typedoc": "bin/typedoc"
- },
- "engines": {
- "node": ">= 18",
- "pnpm": ">= 10"
- },
- "peerDependencies": {
- "typescript": "5.0.x || 5.1.x || 5.2.x || 5.3.x || 5.4.x || 5.5.x || 5.6.x || 5.7.x || 5.8.x || 5.9.x || 6.0.x"
- }
- },
- "node_modules/typescript": {
- "version": "6.0.3",
- "resolved": "https://registry.npmjs.org/typescript/-/typescript-6.0.3.tgz",
- "integrity": "sha512-y2TvuxSZPDyQakkFRPZHKFm+KKVqIisdg9/CZwm9ftvKXLP8NRWj38/ODjNbr43SsoXqNuAisEf1GdCxqWcdBw==",
- "dev": true,
- "license": "Apache-2.0",
- "peer": true,
- "bin": {
- "tsc": "bin/tsc",
- "tsserver": "bin/tsserver"
- },
- "engines": {
- "node": ">=14.17"
- }
- },
- "node_modules/uc.micro": {
- "version": "2.1.0",
- "resolved": "https://registry.npmjs.org/uc.micro/-/uc.micro-2.1.0.tgz",
- "integrity": "sha512-ARDJmphmdvUk6Glw7y9DQ2bFkKBHwQHLi2lsaH6PPmz/Ka9sFOBsBluozhDltWmnv9u/cF6Rt87znRTPV+yp/A==",
- "dev": true,
- "license": "MIT"
- },
- "node_modules/yaml": {
- "version": "2.9.0",
- "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.9.0.tgz",
- "integrity": "sha512-2AvhNX3mb8zd6Zy7INTtSpl1F15HW6Wnqj0srWlkKLcpYl/gMIMJiyuGq2KeI2YFxUPjdlB+3Lc10seMLtL4cA==",
- "dev": true,
- "license": "ISC",
- "bin": {
- "yaml": "bin.mjs"
- },
- "engines": {
- "node": ">= 14.6"
- },
- "funding": {
- "url": "https://github.com/sponsors/eemeli"
- }
- }
- }
-}
diff --git a/impro-plugin/package.json b/impro-plugin/package.json
index 787b81ec..23d84d47 100644
--- a/impro-plugin/package.json
+++ b/impro-plugin/package.json
@@ -14,6 +14,7 @@
"main.js"
],
"devDependencies": {
- "typedoc": "^0.28.20"
+ "typedoc": "^0.28.20",
+ "typedoc-plugin-markdown": "^4.12.0"
}
}
diff --git a/impro-plugin/typedoc.json b/impro-plugin/typedoc.json
index e43536a4..991535ef 100644
--- a/impro-plugin/typedoc.json
+++ b/impro-plugin/typedoc.json
@@ -1,6 +1,21 @@
{
"entryPoints": ["main.js"],
+ "plugin": ["typedoc-plugin-markdown"],
"tsconfig": "tsconfig.typedoc.json",
"out": "docs",
- "excludeInternal": true
+ "excludeInternal": true,
+ "disableSources": true,
+ "router": "module",
+ "mergeReadme": true,
+ "entryFileName": "docs",
+ "hidePageHeader": true,
+ "hideBreadcrumbs": true,
+ "indexFormat": "table",
+ "parametersFormat": "table",
+ "classPropertiesFormat": "table",
+ "interfacePropertiesFormat": "table",
+ "propertyMembersFormat": "table",
+ "typeAliasPropertiesFormat": "table",
+ "typeDeclarationFormat": "table",
+ "enumMembersFormat": "table"
}
diff --git a/package-lock.json b/package-lock.json
index cd017bc2..337c5c4e 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -1,13 +1,16 @@
{
"name": "impro",
- "version": "0.17.138",
+ "version": "0.18.152",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "impro",
- "version": "0.17.138",
+ "version": "0.18.152",
"license": "0BSD",
+ "workspaces": [
+ "impro-plugin"
+ ],
"dependencies": {
"@capacitor/app": "^7.0.0",
"@capacitor/browser": "^7.0.0",
@@ -37,6 +40,15 @@
"typescript": "^5.9.2"
}
},
+ "impro-plugin": {
+ "name": "@impro.social/impro-plugin",
+ "version": "0.0.20",
+ "license": "0BSD",
+ "devDependencies": {
+ "typedoc": "^0.28.20",
+ "typedoc-plugin-markdown": "^4.12.0"
+ }
+ },
"node_modules/@11ty/dependency-tree": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/@11ty/dependency-tree/-/dependency-tree-4.0.0.tgz",
@@ -1498,6 +1510,20 @@
"node": ">=18"
}
},
+ "node_modules/@gerrit0/mini-shiki": {
+ "version": "3.23.0",
+ "resolved": "https://registry.npmjs.org/@gerrit0/mini-shiki/-/mini-shiki-3.23.0.tgz",
+ "integrity": "sha512-bEMORlG0cqdjVyCEuU0cDQbORWX+kYCeo0kV1lbxF5bt4r7SID2l9bqsxJEM0zndaxpOUT7riCyIVEuqq/Ynxg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@shikijs/engine-oniguruma": "^3.23.0",
+ "@shikijs/langs": "^3.23.0",
+ "@shikijs/themes": "^3.23.0",
+ "@shikijs/types": "^3.23.0",
+ "@shikijs/vscode-textmate": "^10.0.2"
+ }
+ },
"node_modules/@import-maps/resolve": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/@import-maps/resolve/-/resolve-2.0.0.tgz",
@@ -1505,6 +1531,10 @@
"dev": true,
"license": "MIT"
},
+ "node_modules/@impro.social/impro-plugin": {
+ "resolved": "impro-plugin",
+ "link": true
+ },
"node_modules/@ionic/cli-framework-output": {
"version": "2.2.8",
"resolved": "https://registry.npmjs.org/@ionic/cli-framework-output/-/cli-framework-output-2.2.8.tgz",
@@ -2303,6 +2333,55 @@
"node": ">=18"
}
},
+ "node_modules/@shikijs/engine-oniguruma": {
+ "version": "3.23.0",
+ "resolved": "https://registry.npmjs.org/@shikijs/engine-oniguruma/-/engine-oniguruma-3.23.0.tgz",
+ "integrity": "sha512-1nWINwKXxKKLqPibT5f4pAFLej9oZzQTsby8942OTlsJzOBZ0MWKiwzMsd+jhzu8YPCHAswGnnN1YtQfirL35g==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@shikijs/types": "3.23.0",
+ "@shikijs/vscode-textmate": "^10.0.2"
+ }
+ },
+ "node_modules/@shikijs/langs": {
+ "version": "3.23.0",
+ "resolved": "https://registry.npmjs.org/@shikijs/langs/-/langs-3.23.0.tgz",
+ "integrity": "sha512-2Ep4W3Re5aB1/62RSYQInK9mM3HsLeB91cHqznAJMuylqjzNVAVCMnNWRHFtcNHXsoNRayP9z1qj4Sq3nMqYXg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@shikijs/types": "3.23.0"
+ }
+ },
+ "node_modules/@shikijs/themes": {
+ "version": "3.23.0",
+ "resolved": "https://registry.npmjs.org/@shikijs/themes/-/themes-3.23.0.tgz",
+ "integrity": "sha512-5qySYa1ZgAT18HR/ypENL9cUSGOeI2x+4IvYJu4JgVJdizn6kG4ia5Q1jDEOi7gTbN4RbuYtmHh0W3eccOrjMA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@shikijs/types": "3.23.0"
+ }
+ },
+ "node_modules/@shikijs/types": {
+ "version": "3.23.0",
+ "resolved": "https://registry.npmjs.org/@shikijs/types/-/types-3.23.0.tgz",
+ "integrity": "sha512-3JZ5HXOZfYjsYSk0yPwBrkupyYSLpAE26Qc0HLghhZNGTZg/SKxXIIgoxOpmmeQP0RRSDJTk1/vPfw9tbw+jSQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@shikijs/vscode-textmate": "^10.0.2",
+ "@types/hast": "^3.0.4"
+ }
+ },
+ "node_modules/@shikijs/vscode-textmate": {
+ "version": "10.0.2",
+ "resolved": "https://registry.npmjs.org/@shikijs/vscode-textmate/-/vscode-textmate-10.0.2.tgz",
+ "integrity": "sha512-83yeghZ2xxin3Nj8z1NMd/NCuca+gsYXswywDy5bHvwlWL8tpTQmzGeUuHd9FC3E/SBEMvzJRwWEOz5gGes9Qg==",
+ "dev": true,
+ "license": "MIT"
+ },
"node_modules/@sinclair/typebox": {
"version": "0.34.41",
"resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.34.41.tgz",
@@ -2429,6 +2508,16 @@
"@types/node": "*"
}
},
+ "node_modules/@types/hast": {
+ "version": "3.0.5",
+ "resolved": "https://registry.npmjs.org/@types/hast/-/hast-3.0.5.tgz",
+ "integrity": "sha512-rp/ezSWaD1m44dPKICGhiskI13nVr7qTloFwDa/IYkhhf5nzwP+zIQcIJh3WIFSBOy/H1PzB40jPjMDksN4F+g==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@types/unist": "*"
+ }
+ },
"node_modules/@types/istanbul-lib-coverage": {
"version": "2.0.6",
"resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.6.tgz",
@@ -2505,6 +2594,13 @@
"integrity": "sha512-ScaPdn1dQczgbl0QFTeTOmVHFULt394XJgOQNoyVhZ6r2vLnMLJfBPd53SB52T/3G36VI1/g2MZaX0cwDuXsfw==",
"license": "MIT"
},
+ "node_modules/@types/unist": {
+ "version": "3.0.3",
+ "resolved": "https://registry.npmjs.org/@types/unist/-/unist-3.0.3.tgz",
+ "integrity": "sha512-ko/gIFJRv177XgZsZcBwnqJN5x/Gien8qNOn0D5bQU/zAzVf9Zt3BlcUiLqhV9y4ARk0GbT3tnUiPNgnTXzc/Q==",
+ "dev": true,
+ "license": "MIT"
+ },
"node_modules/@types/yargs": {
"version": "17.0.34",
"resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.34.tgz",
@@ -5992,10 +6088,20 @@
"license": "MIT"
},
"node_modules/linkify-it": {
- "version": "5.0.0",
- "resolved": "https://registry.npmjs.org/linkify-it/-/linkify-it-5.0.0.tgz",
- "integrity": "sha512-5aHCbzQRADcdP+ATqnDuhhJ/MRIqDkZX5pyjFHRRysS8vZ5AbqGEoFIb6pYHPZ+L/OC2Lc+xT8uHVVR5CAK/wQ==",
+ "version": "5.0.2",
+ "resolved": "https://registry.npmjs.org/linkify-it/-/linkify-it-5.0.2.tgz",
+ "integrity": "sha512-ONTm2jCMAVZjgQa/Fy1kScXsuOoF5NPTsoFBdE1KVIZ2vAh/r9+Bqo+0jINCBYnavTPQZz38QzFTme79ENoN3Q==",
"dev": true,
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/puzrin"
+ },
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/markdown-it"
+ }
+ ],
"license": "MIT",
"dependencies": {
"uc.micro": "^2.0.0"
@@ -6071,6 +6177,13 @@
"yallist": "^3.0.2"
}
},
+ "node_modules/lunr": {
+ "version": "2.3.9",
+ "resolved": "https://registry.npmjs.org/lunr/-/lunr-2.3.9.tgz",
+ "integrity": "sha512-zTU3DaZaF3Rt9rhN3uBMGQD3dD2/vFQqnvZCDv4dl5iOzq2IZQqTxu90r4E5J+nP70J3ilqVCrbho2eWaeW8Ow==",
+ "dev": true,
+ "license": "MIT"
+ },
"node_modules/luxon": {
"version": "3.7.2",
"resolved": "https://registry.npmjs.org/luxon/-/luxon-3.7.2.tgz",
@@ -6108,15 +6221,25 @@
}
},
"node_modules/markdown-it": {
- "version": "14.1.0",
- "resolved": "https://registry.npmjs.org/markdown-it/-/markdown-it-14.1.0.tgz",
- "integrity": "sha512-a54IwgWPaeBCAAsv13YgmALOF1elABB08FxO9i+r4VFk5Vl4pKokRPeX8u5TCgSsPi6ec1otfLjdOpVcgbpshg==",
+ "version": "14.3.0",
+ "resolved": "https://registry.npmjs.org/markdown-it/-/markdown-it-14.3.0.tgz",
+ "integrity": "sha512-RCEsPjR+sr0x+AuYp601tKTkgFG4YEPLCzHST3cQ/fhlJkqAkz1L2/Qbp1j9qw5SBwQHFBoW8+hoN5xssOF0Tw==",
"dev": true,
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/puzrin"
+ },
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/markdown-it"
+ }
+ ],
"license": "MIT",
"dependencies": {
"argparse": "^2.0.1",
- "entities": "^4.4.0",
- "linkify-it": "^5.0.0",
+ "entities": "^4.5.0",
+ "linkify-it": "^5.0.2",
"mdurl": "^2.0.0",
"punycode.js": "^2.3.1",
"uc.micro": "^2.1.0"
@@ -8239,6 +8362,82 @@
"node": ">=4"
}
},
+ "node_modules/typedoc": {
+ "version": "0.28.20",
+ "resolved": "https://registry.npmjs.org/typedoc/-/typedoc-0.28.20.tgz",
+ "integrity": "sha512-uSKqkh8Cr48vllnEy+jdaAgOeR6Y+QCBW7usgUsKj7gJEfR7stw9U/fE49LBnj2tPRKPY0c0EBJSWe9Appmplg==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@gerrit0/mini-shiki": "^3.23.0",
+ "lunr": "^2.3.9",
+ "markdown-it": "^14.3.0",
+ "minimatch": "^10.2.5",
+ "yaml": "^2.9.0"
+ },
+ "bin": {
+ "typedoc": "bin/typedoc"
+ },
+ "engines": {
+ "node": ">= 18",
+ "pnpm": ">= 10"
+ },
+ "peerDependencies": {
+ "typescript": "5.0.x || 5.1.x || 5.2.x || 5.3.x || 5.4.x || 5.5.x || 5.6.x || 5.7.x || 5.8.x || 5.9.x || 6.0.x"
+ }
+ },
+ "node_modules/typedoc-plugin-markdown": {
+ "version": "4.12.0",
+ "resolved": "https://registry.npmjs.org/typedoc-plugin-markdown/-/typedoc-plugin-markdown-4.12.0.tgz",
+ "integrity": "sha512-eJDEMAfxCmede22c/Jw7d0FA13ggAQv+KkwQYKYCdqI02cin6Rc9QRwbG/7XvvHWinuFejySnZVUWDtvGk3Vbg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 18"
+ },
+ "peerDependencies": {
+ "typedoc": "0.28.x"
+ }
+ },
+ "node_modules/typedoc/node_modules/balanced-match": {
+ "version": "4.0.4",
+ "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-4.0.4.tgz",
+ "integrity": "sha512-BLrgEcRTwX2o6gGxGOCNyMvGSp35YofuYzw9h1IMTRmKqttAZZVU67bdb9Pr2vUHA8+j3i2tJfjO6C6+4myGTA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": "18 || 20 || >=22"
+ }
+ },
+ "node_modules/typedoc/node_modules/brace-expansion": {
+ "version": "5.0.9",
+ "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.9.tgz",
+ "integrity": "sha512-ScQ4IuvIEF1TMlP7Zt+vjJ//9zlPb2SDcxWxM3bk8s6t6GGdJ7KO1dCcTidOPJKePW30LE/2cT7wCyPho9/Wxg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "balanced-match": "^4.0.2"
+ },
+ "engines": {
+ "node": "20 || >=22"
+ }
+ },
+ "node_modules/typedoc/node_modules/minimatch": {
+ "version": "10.2.6",
+ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.2.6.tgz",
+ "integrity": "sha512-vpLQEs+VLCr1nU0BXS07maYoFwlDAH0gngQuuttxIwutDFEMHq2blX+8vpgxDdK3J1PwjCJiep77OitTZ4Ll1A==",
+ "dev": true,
+ "license": "BlueOak-1.0.0",
+ "dependencies": {
+ "brace-expansion": "^5.0.8"
+ },
+ "engines": {
+ "node": "18 || 20 || >=22"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/isaacs"
+ }
+ },
"node_modules/typescript": {
"version": "5.9.3",
"resolved": "https://registry.npmjs.org/typescript/-/typescript-5.9.3.tgz",
@@ -8639,6 +8838,22 @@
"dev": true,
"license": "ISC"
},
+ "node_modules/yaml": {
+ "version": "2.9.0",
+ "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.9.0.tgz",
+ "integrity": "sha512-2AvhNX3mb8zd6Zy7INTtSpl1F15HW6Wnqj0srWlkKLcpYl/gMIMJiyuGq2KeI2YFxUPjdlB+3Lc10seMLtL4cA==",
+ "dev": true,
+ "license": "ISC",
+ "bin": {
+ "yaml": "bin.mjs"
+ },
+ "engines": {
+ "node": ">= 14.6"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/eemeli"
+ }
+ },
"node_modules/yargs": {
"version": "17.7.2",
"resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz",
diff --git a/package.json b/package.json
index 30429ff2..dba64a6e 100644
--- a/package.json
+++ b/package.json
@@ -19,6 +19,9 @@
"serve:static": "node scripts/serve-static.js",
"prepare": "husky"
},
+ "workspaces": [
+ "impro-plugin"
+ ],
"license": "0BSD",
"devDependencies": {
"@11ty/eleventy": "^3.1.2",