Compare commits
8 commits
18b616f042
...
3303ae4be0
| Author | SHA1 | Date | |
|---|---|---|---|
| 3303ae4be0 | |||
| f9582d3c7b | |||
| 90599c2e7c | |||
| ea3aa1413f | |||
| 34152dabc3 | |||
| b159b4c00a | |||
| 97b897a557 | |||
| dfa904042e |
46 changed files with 3931 additions and 12571 deletions
41
.forgejo/workflows/botlib.yaml
Normal file
41
.forgejo/workflows/botlib.yaml
Normal file
|
|
@ -0,0 +1,41 @@
|
|||
name: GBCI
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: ["main"]
|
||||
pull_request:
|
||||
branches: ["main"]
|
||||
|
||||
jobs:
|
||||
build:
|
||||
runs-on: gbo
|
||||
|
||||
steps:
|
||||
- name: Disable SSL verification (temporary)
|
||||
run: git config --global http.sslVerify false
|
||||
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- name: Install Rust
|
||||
uses: msrd0/rust-toolchain@v1
|
||||
with:
|
||||
toolchain: stable
|
||||
|
||||
- name: Build library (default features)
|
||||
run: cargo build --locked
|
||||
|
||||
- name: Build library (full features)
|
||||
run: cargo build --locked --features full
|
||||
|
||||
- name: Run tests
|
||||
run: cargo test --locked --features full
|
||||
|
||||
- name: Build release
|
||||
run: cargo build --locked --release --features full
|
||||
|
||||
- name: Deploy library
|
||||
run: |
|
||||
sudo mkdir -p /opt/gbo/lib/botlib
|
||||
sudo cp ./target/release/libbotlib.rlib /opt/gbo/lib/botlib/ || true
|
||||
sudo cp ./target/release/libbotlib.a /opt/gbo/lib/botlib/ || true
|
||||
sudo cp ./target/release/libbotlib.so /opt/gbo/lib/botlib/ || true
|
||||
20
.gitignore
vendored
20
.gitignore
vendored
|
|
@ -1,5 +1,15 @@
|
|||
node_modules
|
||||
docs
|
||||
dist
|
||||
xx.xx
|
||||
xx.yy
|
||||
.tmp*
|
||||
.tmp/*
|
||||
*.log
|
||||
target*
|
||||
.env
|
||||
target
|
||||
*.env
|
||||
work
|
||||
*.out
|
||||
bin
|
||||
botserver-stack
|
||||
*logfile*
|
||||
*-log*
|
||||
docs/book
|
||||
*.rdb
|
||||
|
|
|
|||
|
|
@ -1,2 +0,0 @@
|
|||
node_modules
|
||||
docs
|
||||
|
|
@ -1,8 +0,0 @@
|
|||
{
|
||||
"trailingComma": "none",
|
||||
"tabWidth": 2,
|
||||
"printWidth": 120,
|
||||
"arrowParens": "avoid",
|
||||
"semi": true,
|
||||
"singleQuote": true
|
||||
}
|
||||
2119
Cargo.lock
generated
Normal file
2119
Cargo.lock
generated
Normal file
File diff suppressed because it is too large
Load diff
38
Cargo.toml
Normal file
38
Cargo.toml
Normal file
|
|
@ -0,0 +1,38 @@
|
|||
[package]
|
||||
name = "botlib"
|
||||
version = "6.1.0"
|
||||
edition = "2021"
|
||||
description = "Shared library for General Bots - common types, utilities, and HTTP client"
|
||||
license = "AGPL-3.0"
|
||||
authors = ["Pragmatismo.com.br", "General Bots Community"]
|
||||
repository = "https://github.com/GeneralBots/BotServer"
|
||||
|
||||
[features]
|
||||
default = []
|
||||
full = ["database", "http-client", "validation"]
|
||||
database = ["dep:diesel"]
|
||||
http-client = ["dep:reqwest"]
|
||||
validation = ["dep:validator"]
|
||||
|
||||
[dependencies]
|
||||
# Core
|
||||
anyhow = "1.0"
|
||||
thiserror = "2.0"
|
||||
log = "0.4"
|
||||
chrono = { version = "0.4", features = ["serde"] }
|
||||
serde = { version = "1.0", features = ["derive"] }
|
||||
serde_json = "1.0"
|
||||
uuid = { version = "1.11", features = ["serde", "v4"] }
|
||||
toml = "0.8"
|
||||
|
||||
# Optional: Database
|
||||
diesel = { version = "2.1", features = ["postgres", "uuid", "chrono", "serde_json", "r2d2"], optional = true }
|
||||
|
||||
# Optional: HTTP Client
|
||||
reqwest = { version = "0.12", features = ["json"], optional = true }
|
||||
|
||||
# Optional: Validation
|
||||
validator = { version = "0.18", features = ["derive"], optional = true }
|
||||
|
||||
[dev-dependencies]
|
||||
tokio = { version = "1.41", features = ["rt", "macros"] }
|
||||
262
PROMPT.md
Normal file
262
PROMPT.md
Normal file
|
|
@ -0,0 +1,262 @@
|
|||
# BotLib Development Prompt Guide
|
||||
|
||||
**Version:** 6.1.0
|
||||
**Purpose:** LLM context for BotLib shared library development
|
||||
|
||||
---
|
||||
|
||||
## Version Management - CRITICAL
|
||||
|
||||
**Current version is 6.1.0 - DO NOT CHANGE without explicit approval!**
|
||||
|
||||
### Rules
|
||||
|
||||
1. **Version is 6.1.0 across ALL workspace crates**
|
||||
2. **NEVER change version without explicit user approval**
|
||||
3. **All workspace crates share version 6.1.0**
|
||||
4. **BotLib does not have migrations - all migrations are in botserver/**
|
||||
|
||||
---
|
||||
|
||||
## Official Icons - Reference
|
||||
|
||||
**BotLib does not contain icons.** Icons are managed in:
|
||||
- `botui/ui/suite/assets/icons/` - Runtime UI icons
|
||||
- `botbook/src/assets/icons/` - Documentation icons
|
||||
|
||||
When documenting or referencing UI elements in BotLib:
|
||||
- Reference icons by name (e.g., `gb-chat.svg`, `gb-drive.svg`)
|
||||
- Never generate or embed icon content
|
||||
- See `botui/PROMPT.md` for the complete icon list
|
||||
|
||||
---
|
||||
|
||||
## Project Overview
|
||||
|
||||
BotLib is the shared foundation library for the General Bots workspace. It provides common types, utilities, error handling, and optional integrations that are consumed by botserver, botui, and botapp.
|
||||
|
||||
### Workspace Position
|
||||
|
||||
```
|
||||
botlib/ # THIS PROJECT - Shared library
|
||||
botserver/ # Main server (depends on botlib)
|
||||
botui/ # Web/Desktop UI (depends on botlib)
|
||||
botapp/ # Desktop app (depends on botlib)
|
||||
botbook/ # Documentation
|
||||
```
|
||||
|
||||
### What BotLib Provides
|
||||
|
||||
- **Error Types**: Common error handling with anyhow/thiserror
|
||||
- **Models**: Shared data structures and types
|
||||
- **HTTP Client**: Optional reqwest wrapper
|
||||
- **Database**: Optional diesel integration
|
||||
- **Validation**: Optional input validation
|
||||
- **Branding**: Version and branding constants
|
||||
|
||||
---
|
||||
|
||||
## Feature Flags
|
||||
|
||||
```toml
|
||||
[features]
|
||||
default = []
|
||||
full = ["database", "http-client", "validation"]
|
||||
database = ["dep:diesel"]
|
||||
http-client = ["dep:reqwest"]
|
||||
validation = ["dep:validator"]
|
||||
```
|
||||
|
||||
### Usage in Dependent Crates
|
||||
|
||||
```toml
|
||||
# botserver/Cargo.toml
|
||||
[dependencies.botlib]
|
||||
path = "../botlib"
|
||||
features = ["database"]
|
||||
|
||||
# botui/Cargo.toml
|
||||
[dependencies.botlib]
|
||||
path = "../botlib"
|
||||
features = ["http-client"]
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Code Generation Rules
|
||||
|
||||
### CRITICAL REQUIREMENTS
|
||||
|
||||
```
|
||||
- Library code must be generic and reusable
|
||||
- No hardcoded values or project-specific logic
|
||||
- All public APIs must be well-documented
|
||||
- Feature gates for optional dependencies
|
||||
- Zero warnings - clean compilation required
|
||||
```
|
||||
|
||||
### Module Structure
|
||||
|
||||
```
|
||||
src/
|
||||
├── lib.rs # Public exports, feature gates
|
||||
├── error.rs # Error types (thiserror)
|
||||
├── models.rs # Shared data models
|
||||
├── message_types.rs # Message type definitions
|
||||
├── http_client.rs # HTTP client wrapper (feature-gated)
|
||||
├── branding.rs # Version, branding constants
|
||||
└── version.rs # Version information
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Adding New Features
|
||||
|
||||
### Adding a Shared Type
|
||||
|
||||
```rust
|
||||
// src/models.rs
|
||||
use chrono::{DateTime, Utc};
|
||||
use serde::{Deserialize, Serialize};
|
||||
use uuid::Uuid;
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
pub struct SharedEntity {
|
||||
pub id: Uuid,
|
||||
pub name: String,
|
||||
pub created_at: DateTime<Utc>,
|
||||
}
|
||||
```
|
||||
|
||||
### Adding a Feature-Gated Module
|
||||
|
||||
```rust
|
||||
// src/lib.rs
|
||||
#[cfg(feature = "my-feature")]
|
||||
pub mod my_module;
|
||||
|
||||
#[cfg(feature = "my-feature")]
|
||||
pub use my_module::MyType;
|
||||
```
|
||||
|
||||
```toml
|
||||
# Cargo.toml
|
||||
[features]
|
||||
my-feature = ["dep:some-crate"]
|
||||
|
||||
[dependencies]
|
||||
some-crate = { version = "1.0", optional = true }
|
||||
```
|
||||
|
||||
### Adding Error Types
|
||||
|
||||
```rust
|
||||
// src/error.rs
|
||||
use thiserror::Error;
|
||||
|
||||
#[derive(Error, Debug)]
|
||||
pub enum BotLibError {
|
||||
#[error("Configuration error: {0}")]
|
||||
Config(String),
|
||||
|
||||
#[error("HTTP error: {0}")]
|
||||
Http(#[from] reqwest::Error),
|
||||
|
||||
#[error("Database error: {0}")]
|
||||
Database(String),
|
||||
}
|
||||
|
||||
pub type Result<T> = std::result::Result<T, BotLibError>;
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Re-exports Strategy
|
||||
|
||||
BotLib should re-export common dependencies to ensure version consistency:
|
||||
|
||||
```rust
|
||||
// src/lib.rs
|
||||
pub use anyhow;
|
||||
pub use chrono;
|
||||
pub use serde;
|
||||
pub use serde_json;
|
||||
pub use thiserror;
|
||||
pub use uuid;
|
||||
|
||||
#[cfg(feature = "database")]
|
||||
pub use diesel;
|
||||
|
||||
#[cfg(feature = "http-client")]
|
||||
pub use reqwest;
|
||||
```
|
||||
|
||||
Consumers then use:
|
||||
|
||||
```rust
|
||||
use botlib::uuid::Uuid;
|
||||
use botlib::chrono::Utc;
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Dependencies
|
||||
|
||||
| Library | Version | Purpose | Optional |
|
||||
|---------|---------|---------|----------|
|
||||
| anyhow | 1.0 | Error handling | No |
|
||||
| thiserror | 2.0 | Error derive | No |
|
||||
| log | 0.4 | Logging facade | No |
|
||||
| chrono | 0.4 | Date/time | No |
|
||||
| serde | 1.0 | Serialization | No |
|
||||
| serde_json | 1.0 | JSON | No |
|
||||
| uuid | 1.11 | UUIDs | No |
|
||||
| toml | 0.8 | Config parsing | No |
|
||||
| diesel | 2.1 | Database ORM | Yes |
|
||||
| reqwest | 0.12 | HTTP client | Yes |
|
||||
| validator | 0.18 | Validation | Yes |
|
||||
|
||||
---
|
||||
|
||||
## Testing
|
||||
|
||||
```bash
|
||||
# Test all features
|
||||
cargo test --all-features
|
||||
|
||||
# Test specific feature
|
||||
cargo test --features database
|
||||
|
||||
# Test without optional features
|
||||
cargo test
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Final Checks Before Commit
|
||||
|
||||
```bash
|
||||
# Verify version is 6.1.0
|
||||
grep "^version" Cargo.toml | grep "6.1.0"
|
||||
|
||||
# Build with all features
|
||||
cargo build --all-features
|
||||
|
||||
# Check for warnings
|
||||
cargo check --all-features 2>&1 | grep warning
|
||||
|
||||
# Run tests
|
||||
cargo test --all-features
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Rules
|
||||
|
||||
- Keep botlib minimal and focused
|
||||
- No business logic - only utilities and types
|
||||
- Feature gate all optional dependencies
|
||||
- Maintain backward compatibility
|
||||
- Document all public APIs
|
||||
- Target zero warnings
|
||||
- **Version**: Always 6.1.0 - do not change without approval
|
||||
|
|
@ -1,3 +1,3 @@
|
|||
General Bots® base library for building Node.js TypeScript Apps packages (.gbapp).
|
||||
|
||||
See: https://github.com/pragmatismo-io/BotServer for main documentation.
|
||||
See: https://github.com/pragmatismo-io/botserver for main documentation.
|
||||
107
VERSION.md
107
VERSION.md
|
|
@ -1,107 +0,0 @@
|
|||
# History
|
||||
|
||||
## Version 0.1.6
|
||||
|
||||
* References and version updated.
|
||||
|
||||
## Version 0.1.5
|
||||
|
||||
* Docs updated.
|
||||
|
||||
## Version 0.1.4
|
||||
|
||||
* New fields to 100% automated development environement setup.
|
||||
|
||||
## Version 0.1.3
|
||||
|
||||
- FIX: Updated dependencies versions.
|
||||
|
||||
## Version 0.1.2
|
||||
|
||||
- NEW: pragmatismo-io-framework updated.
|
||||
|
||||
## Version 0.1.0
|
||||
|
||||
- NEW: Migration to Bot Framework v4.
|
||||
|
||||
## Version 0.0.33
|
||||
|
||||
- FIX: Updated dependencies versions.
|
||||
|
||||
## Version 0.0.32
|
||||
|
||||
- FIX: Updated dependencies versions.
|
||||
|
||||
## Version 0.0.31
|
||||
|
||||
- FIX: Export of Sequelize from sequelize-typescript.
|
||||
|
||||
## Version 0.0.30
|
||||
|
||||
- FIX: Packages updated.
|
||||
- FIX: Missing some 'use strict'.
|
||||
|
||||
## Version 0.0.29
|
||||
|
||||
- FIX: Packages updated.
|
||||
|
||||
## Version 0.0.28
|
||||
|
||||
- FIX: Package compiled.
|
||||
|
||||
## Version 0.0.27
|
||||
|
||||
- FIX: Merged changes.
|
||||
|
||||
## Version 0.0.26
|
||||
|
||||
- NEW: Support for Speech recognition/synthesis.
|
||||
|
||||
## Version 0.0.25
|
||||
|
||||
- FIX: Packages updated.
|
||||
|
||||
## Version 0.0.24
|
||||
|
||||
- FIX: Packages updated.
|
||||
|
||||
## Version 0.0.23
|
||||
|
||||
- FIX: Trying to remove botbuilder dependency on hoek vunerability with no success, MS is promissing update it: https://github.com/Microsoft/BotBuilder/issues/4206.
|
||||
|
||||
## Version 0.0.22
|
||||
|
||||
- FIX: Packages updated.
|
||||
|
||||
## Version 0.0.21
|
||||
|
||||
- FIX: Whatsapp directline client improved.
|
||||
|
||||
## Version 0.0.20
|
||||
|
||||
- NEW: Whatsapp directline client is now working in preview.
|
||||
- NEW: Parameter whatsappServiceWebhookUrl added.
|
||||
|
||||
## Version 0.0.19
|
||||
|
||||
- NEW: Parameter whatsappServiceUrl added to support other whatsapp channels.
|
||||
|
||||
## Version 0.0.18
|
||||
|
||||
- FIX: Missing TS compilation.
|
||||
|
||||
## Version 0.0.17
|
||||
|
||||
- NEW: The bot now has an associated mobile Whatsapp number;
|
||||
|
||||
## Version 0.0.16
|
||||
|
||||
- FIX: Compilation of Typescript into JavaScript.
|
||||
|
||||
## Version 0.0.15
|
||||
|
||||
- NEW: Now each .gbapp has it own set of syspackages loaded.
|
||||
|
||||
## Version 0.0.14
|
||||
|
||||
- NEW: Added support for Whatsapp external service key on bot instance model.
|
||||
|
|
@ -1,865 +0,0 @@
|
|||
/*! normalize.css v1.1.3 | MIT License | git.io/normalize */
|
||||
/* ========================================================================== HTML5 display definitions ========================================================================== */
|
||||
/** Correct `block` display not defined in IE 6/7/8/9 and Firefox 3. */
|
||||
article, aside, details, figcaption, figure, footer, header, hgroup, main, nav, section, summary { display: block; }
|
||||
|
||||
/** Correct `inline-block` display not defined in IE 6/7/8/9 and Firefox 3. */
|
||||
audio, canvas, video { display: inline-block; *display: inline; *zoom: 1; }
|
||||
|
||||
/** Prevent modern browsers from displaying `audio` without controls. Remove excess height in iOS 5 devices. */
|
||||
audio:not([controls]) { display: none; height: 0; }
|
||||
|
||||
/** Address styling not present in IE 7/8/9, Firefox 3, and Safari 4. Known issue: no IE 6 support. */
|
||||
[hidden] { display: none; }
|
||||
|
||||
/* ========================================================================== Base ========================================================================== */
|
||||
/** 1. Correct text resizing oddly in IE 6/7 when body `font-size` is set using `em` units. 2. Prevent iOS text size adjust after orientation change, without disabling user zoom. */
|
||||
html { font-size: 100%; /* 1 */ -ms-text-size-adjust: 100%; /* 2 */ -webkit-text-size-adjust: 100%; /* 2 */ font-family: sans-serif; }
|
||||
|
||||
/** Address `font-family` inconsistency between `textarea` and other form elements. */
|
||||
button, input, select, textarea { font-family: sans-serif; }
|
||||
|
||||
/** Address margins handled incorrectly in IE 6/7. */
|
||||
body { margin: 0; }
|
||||
|
||||
/* ========================================================================== Links ========================================================================== */
|
||||
/** Address `outline` inconsistency between Chrome and other browsers. */
|
||||
a:focus { outline: thin dotted; }
|
||||
a:active, a:hover { outline: 0; }
|
||||
|
||||
/** Improve readability when focused and also mouse hovered in all browsers. */
|
||||
/* ========================================================================== Typography ========================================================================== */
|
||||
/** Address font sizes and margins set differently in IE 6/7. Address font sizes within `section` and `article` in Firefox 4+, Safari 5, and Chrome. */
|
||||
h1 { font-size: 2em; margin: 0.67em 0; }
|
||||
|
||||
h2 { font-size: 1.5em; margin: 0.83em 0; }
|
||||
|
||||
h3 { font-size: 1.17em; margin: 1em 0; }
|
||||
|
||||
h4, .tsd-index-panel h3 { font-size: 1em; margin: 1.33em 0; }
|
||||
|
||||
h5 { font-size: 0.83em; margin: 1.67em 0; }
|
||||
|
||||
h6 { font-size: 0.67em; margin: 2.33em 0; }
|
||||
|
||||
/** Address styling not present in IE 7/8/9, Safari 5, and Chrome. */
|
||||
abbr[title] { border-bottom: 1px dotted; }
|
||||
|
||||
/** Address style set to `bolder` in Firefox 3+, Safari 4/5, and Chrome. */
|
||||
b, strong { font-weight: bold; }
|
||||
|
||||
blockquote { margin: 1em 40px; }
|
||||
|
||||
/** Address styling not present in Safari 5 and Chrome. */
|
||||
dfn { font-style: italic; }
|
||||
|
||||
/** Address differences between Firefox and other browsers. Known issue: no IE 6/7 normalization. */
|
||||
hr { box-sizing: content-box; height: 0; }
|
||||
|
||||
/** Address styling not present in IE 6/7/8/9. */
|
||||
mark { background: #ff0; color: #000; }
|
||||
|
||||
/** Address margins set differently in IE 6/7. */
|
||||
p, pre { margin: 1em 0; }
|
||||
|
||||
/** Correct font family set oddly in IE 6, Safari 4/5, and Chrome. */
|
||||
code, kbd, pre, samp { font-family: monospace, serif; _font-family: "courier new", monospace; font-size: 1em; }
|
||||
|
||||
/** Improve readability of pre-formatted text in all browsers. */
|
||||
pre { white-space: pre; white-space: pre-wrap; word-wrap: break-word; }
|
||||
|
||||
/** Address CSS quotes not supported in IE 6/7. */
|
||||
q { quotes: none; }
|
||||
q:before, q:after { content: ""; content: none; }
|
||||
|
||||
/** Address `quotes` property not supported in Safari 4. */
|
||||
/** Address inconsistent and variable font size in all browsers. */
|
||||
small { font-size: 80%; }
|
||||
|
||||
/** Prevent `sub` and `sup` affecting `line-height` in all browsers. */
|
||||
sub { font-size: 75%; line-height: 0; position: relative; vertical-align: baseline; }
|
||||
|
||||
sup { font-size: 75%; line-height: 0; position: relative; vertical-align: baseline; top: -0.5em; }
|
||||
|
||||
sub { bottom: -0.25em; }
|
||||
|
||||
/* ========================================================================== Lists ========================================================================== */
|
||||
/** Address margins set differently in IE 6/7. */
|
||||
dl, menu, ol, ul { margin: 1em 0; }
|
||||
|
||||
dd { margin: 0 0 0 40px; }
|
||||
|
||||
/** Address paddings set differently in IE 6/7. */
|
||||
menu, ol, ul { padding: 0 0 0 40px; }
|
||||
|
||||
/** Correct list images handled incorrectly in IE 7. */
|
||||
nav ul, nav ol { list-style: none; list-style-image: none; }
|
||||
|
||||
/* ========================================================================== Embedded content ========================================================================== */
|
||||
/** 1. Remove border when inside `a` element in IE 6/7/8/9 and Firefox 3. 2. Improve image quality when scaled in IE 7. */
|
||||
img { border: 0; /* 1 */ -ms-interpolation-mode: bicubic; }
|
||||
|
||||
/* 2 */
|
||||
/** Correct overflow displayed oddly in IE 9. */
|
||||
svg:not(:root) { overflow: hidden; }
|
||||
|
||||
/* ========================================================================== Figures ========================================================================== */
|
||||
/** Address margin not present in IE 6/7/8/9, Safari 5, and Opera 11. */
|
||||
figure, form { margin: 0; }
|
||||
|
||||
/* ========================================================================== Forms ========================================================================== */
|
||||
/** Correct margin displayed oddly in IE 6/7. */
|
||||
/** Define consistent border, margin, and padding. */
|
||||
fieldset { border: 1px solid #c0c0c0; margin: 0 2px; padding: 0.35em 0.625em 0.75em; }
|
||||
|
||||
/** 1. Correct color not being inherited in IE 6/7/8/9. 2. Correct text not wrapping in Firefox 3. 3. Correct alignment displayed oddly in IE 6/7. */
|
||||
legend { border: 0; /* 1 */ padding: 0; white-space: normal; /* 2 */ *margin-left: -7px; }
|
||||
|
||||
/* 3 */
|
||||
/** 1. Correct font size not being inherited in all browsers. 2. Address margins set differently in IE 6/7, Firefox 3+, Safari 5, and Chrome. 3. Improve appearance and consistency in all browsers. */
|
||||
button, input, select, textarea { font-size: 100%; /* 1 */ margin: 0; /* 2 */ vertical-align: baseline; /* 3 */ *vertical-align: middle; }
|
||||
|
||||
/* 3 */
|
||||
/** Address Firefox 3+ setting `line-height` on `input` using `!important` in the UA stylesheet. */
|
||||
button, input { line-height: normal; }
|
||||
|
||||
/** Address inconsistent `text-transform` inheritance for `button` and `select`. All other form control elements do not inherit `text-transform` values. Correct `button` style inheritance in Chrome, Safari 5+, and IE 6+. Correct `select` style inheritance in Firefox 4+ and Opera. */
|
||||
button, select { text-transform: none; }
|
||||
|
||||
/** 1. Avoid the WebKit bug in Android 4.0.* where (2) destroys native `audio` and `video` controls. 2. Correct inability to style clickable `input` types in iOS. 3. Improve usability and consistency of cursor style between image-type `input` and others. 4. Remove inner spacing in IE 7 without affecting normal text inputs. Known issue: inner spacing remains in IE 6. */
|
||||
button, html input[type="button"] { -webkit-appearance: button; /* 2 */ cursor: pointer; /* 3 */ *overflow: visible; }
|
||||
|
||||
/* 4 */
|
||||
input[type="reset"], input[type="submit"] { -webkit-appearance: button; /* 2 */ cursor: pointer; /* 3 */ *overflow: visible; }
|
||||
|
||||
/* 4 */
|
||||
/** Re-set default cursor for disabled elements. */
|
||||
button[disabled], html input[disabled] { cursor: default; }
|
||||
|
||||
/** 1. Address box sizing set to content-box in IE 8/9. 2. Remove excess padding in IE 8/9. 3. Remove excess padding in IE 7. Known issue: excess padding remains in IE 6. */
|
||||
input { /* 3 */ }
|
||||
input[type="checkbox"], input[type="radio"] { box-sizing: border-box; /* 1 */ padding: 0; /* 2 */ *height: 13px; /* 3 */ *width: 13px; }
|
||||
input[type="search"] { -webkit-appearance: textfield; /* 1 */ /* 2 */ box-sizing: content-box; }
|
||||
input[type="search"]::-webkit-search-cancel-button, input[type="search"]::-webkit-search-decoration { -webkit-appearance: none; }
|
||||
|
||||
/** 1. Address `appearance` set to `searchfield` in Safari 5 and Chrome. 2. Address `box-sizing` set to `border-box` in Safari 5 and Chrome (include `-moz` to future-proof). */
|
||||
/** Remove inner padding and search cancel button in Safari 5 and Chrome on OS X. */
|
||||
/** Remove inner padding and border in Firefox 3+. */
|
||||
button::-moz-focus-inner, input::-moz-focus-inner { border: 0; padding: 0; }
|
||||
|
||||
/** 1. Remove default vertical scrollbar in IE 6/7/8/9. 2. Improve readability and alignment in all browsers. */
|
||||
textarea { overflow: auto; /* 1 */ vertical-align: top; }
|
||||
|
||||
/* 2 */
|
||||
/* ========================================================================== Tables ========================================================================== */
|
||||
/** Remove most spacing between table cells. */
|
||||
table { border-collapse: collapse; border-spacing: 0; }
|
||||
|
||||
/* Visual Studio-like style based on original C# coloring by Jason Diamond <jason@diamond.name> */
|
||||
.hljs { display: inline-block; padding: 0.5em; background: white; color: black; }
|
||||
|
||||
.hljs-comment, .hljs-annotation, .hljs-template_comment, .diff .hljs-header, .hljs-chunk, .apache .hljs-cbracket { color: #008000; }
|
||||
|
||||
.hljs-keyword, .hljs-id, .hljs-built_in, .css .smalltalk .hljs-class, .hljs-winutils, .bash .hljs-variable, .tex .hljs-command, .hljs-request, .hljs-status, .nginx .hljs-title { color: #00f; }
|
||||
|
||||
.xml .hljs-tag { color: #00f; }
|
||||
.xml .hljs-tag .hljs-value { color: #00f; }
|
||||
|
||||
.hljs-string, .hljs-title, .hljs-parent, .hljs-tag .hljs-value, .hljs-rules .hljs-value { color: #a31515; }
|
||||
|
||||
.ruby .hljs-symbol { color: #a31515; }
|
||||
.ruby .hljs-symbol .hljs-string { color: #a31515; }
|
||||
|
||||
.hljs-template_tag, .django .hljs-variable, .hljs-addition, .hljs-flow, .hljs-stream, .apache .hljs-tag, .hljs-date, .tex .hljs-formula, .coffeescript .hljs-attribute { color: #a31515; }
|
||||
|
||||
.ruby .hljs-string, .hljs-decorator, .hljs-filter .hljs-argument, .hljs-localvars, .hljs-array, .hljs-attr_selector, .hljs-pseudo, .hljs-pi, .hljs-doctype, .hljs-deletion, .hljs-envvar, .hljs-shebang, .hljs-preprocessor, .hljs-pragma, .userType, .apache .hljs-sqbracket, .nginx .hljs-built_in, .tex .hljs-special, .hljs-prompt { color: #2b91af; }
|
||||
|
||||
.hljs-phpdoc, .hljs-javadoc, .hljs-xmlDocTag { color: #808080; }
|
||||
|
||||
.vhdl .hljs-typename { font-weight: bold; }
|
||||
.vhdl .hljs-string { color: #666666; }
|
||||
.vhdl .hljs-literal { color: #a31515; }
|
||||
.vhdl .hljs-attribute { color: #00b0e8; }
|
||||
|
||||
.xml .hljs-attribute { color: #f00; }
|
||||
|
||||
.col > :first-child, .col-1 > :first-child, .col-2 > :first-child, .col-3 > :first-child, .col-4 > :first-child, .col-5 > :first-child, .col-6 > :first-child, .col-7 > :first-child, .col-8 > :first-child, .col-9 > :first-child, .col-10 > :first-child, .col-11 > :first-child, .tsd-panel > :first-child, ul.tsd-descriptions > li > :first-child, .col > :first-child > :first-child, .col-1 > :first-child > :first-child, .col-2 > :first-child > :first-child, .col-3 > :first-child > :first-child, .col-4 > :first-child > :first-child, .col-5 > :first-child > :first-child, .col-6 > :first-child > :first-child, .col-7 > :first-child > :first-child, .col-8 > :first-child > :first-child, .col-9 > :first-child > :first-child, .col-10 > :first-child > :first-child, .col-11 > :first-child > :first-child, .tsd-panel > :first-child > :first-child, ul.tsd-descriptions > li > :first-child > :first-child, .col > :first-child > :first-child > :first-child, .col-1 > :first-child > :first-child > :first-child, .col-2 > :first-child > :first-child > :first-child, .col-3 > :first-child > :first-child > :first-child, .col-4 > :first-child > :first-child > :first-child, .col-5 > :first-child > :first-child > :first-child, .col-6 > :first-child > :first-child > :first-child, .col-7 > :first-child > :first-child > :first-child, .col-8 > :first-child > :first-child > :first-child, .col-9 > :first-child > :first-child > :first-child, .col-10 > :first-child > :first-child > :first-child, .col-11 > :first-child > :first-child > :first-child, .tsd-panel > :first-child > :first-child > :first-child, ul.tsd-descriptions > li > :first-child > :first-child > :first-child { margin-top: 0; }
|
||||
.col > :last-child, .col-1 > :last-child, .col-2 > :last-child, .col-3 > :last-child, .col-4 > :last-child, .col-5 > :last-child, .col-6 > :last-child, .col-7 > :last-child, .col-8 > :last-child, .col-9 > :last-child, .col-10 > :last-child, .col-11 > :last-child, .tsd-panel > :last-child, ul.tsd-descriptions > li > :last-child, .col > :last-child > :last-child, .col-1 > :last-child > :last-child, .col-2 > :last-child > :last-child, .col-3 > :last-child > :last-child, .col-4 > :last-child > :last-child, .col-5 > :last-child > :last-child, .col-6 > :last-child > :last-child, .col-7 > :last-child > :last-child, .col-8 > :last-child > :last-child, .col-9 > :last-child > :last-child, .col-10 > :last-child > :last-child, .col-11 > :last-child > :last-child, .tsd-panel > :last-child > :last-child, ul.tsd-descriptions > li > :last-child > :last-child, .col > :last-child > :last-child > :last-child, .col-1 > :last-child > :last-child > :last-child, .col-2 > :last-child > :last-child > :last-child, .col-3 > :last-child > :last-child > :last-child, .col-4 > :last-child > :last-child > :last-child, .col-5 > :last-child > :last-child > :last-child, .col-6 > :last-child > :last-child > :last-child, .col-7 > :last-child > :last-child > :last-child, .col-8 > :last-child > :last-child > :last-child, .col-9 > :last-child > :last-child > :last-child, .col-10 > :last-child > :last-child > :last-child, .col-11 > :last-child > :last-child > :last-child, .tsd-panel > :last-child > :last-child > :last-child, ul.tsd-descriptions > li > :last-child > :last-child > :last-child { margin-bottom: 0; }
|
||||
|
||||
.container { max-width: 1200px; margin: 0 auto; padding: 0 40px; }
|
||||
@media (max-width: 640px) { .container { padding: 0 20px; } }
|
||||
|
||||
.container-main { padding-bottom: 200px; }
|
||||
|
||||
.row { position: relative; margin: 0 -10px; }
|
||||
.row:after { visibility: hidden; display: block; content: ""; clear: both; height: 0; }
|
||||
|
||||
.col, .col-1, .col-2, .col-3, .col-4, .col-5, .col-6, .col-7, .col-8, .col-9, .col-10, .col-11 { box-sizing: border-box; float: left; padding: 0 10px; }
|
||||
|
||||
.col-1 { width: 8.33333%; }
|
||||
|
||||
.offset-1 { margin-left: 8.33333%; }
|
||||
|
||||
.col-2 { width: 16.66667%; }
|
||||
|
||||
.offset-2 { margin-left: 16.66667%; }
|
||||
|
||||
.col-3 { width: 25%; }
|
||||
|
||||
.offset-3 { margin-left: 25%; }
|
||||
|
||||
.col-4 { width: 33.33333%; }
|
||||
|
||||
.offset-4 { margin-left: 33.33333%; }
|
||||
|
||||
.col-5 { width: 41.66667%; }
|
||||
|
||||
.offset-5 { margin-left: 41.66667%; }
|
||||
|
||||
.col-6 { width: 50%; }
|
||||
|
||||
.offset-6 { margin-left: 50%; }
|
||||
|
||||
.col-7 { width: 58.33333%; }
|
||||
|
||||
.offset-7 { margin-left: 58.33333%; }
|
||||
|
||||
.col-8 { width: 66.66667%; }
|
||||
|
||||
.offset-8 { margin-left: 66.66667%; }
|
||||
|
||||
.col-9 { width: 75%; }
|
||||
|
||||
.offset-9 { margin-left: 75%; }
|
||||
|
||||
.col-10 { width: 83.33333%; }
|
||||
|
||||
.offset-10 { margin-left: 83.33333%; }
|
||||
|
||||
.col-11 { width: 91.66667%; }
|
||||
|
||||
.offset-11 { margin-left: 91.66667%; }
|
||||
|
||||
.tsd-kind-icon { display: block; position: relative; padding-left: 20px; text-indent: -20px; }
|
||||
.tsd-kind-icon:before { content: ''; display: inline-block; vertical-align: middle; width: 17px; height: 17px; margin: 0 3px 2px 0; background-image: url(../images/icons.png); }
|
||||
@media (-webkit-min-device-pixel-ratio: 1.5), (min-device-pixel-ratio: 1.5), (min-resolution: 144dpi) { .tsd-kind-icon:before { background-image: url(../images/icons@2x.png); background-size: 238px 204px; } }
|
||||
|
||||
.tsd-signature.tsd-kind-icon:before { background-position: 0 -153px; }
|
||||
|
||||
.tsd-kind-object-literal > .tsd-kind-icon:before { background-position: 0px -17px; }
|
||||
.tsd-kind-object-literal.tsd-is-protected > .tsd-kind-icon:before { background-position: -17px -17px; }
|
||||
.tsd-kind-object-literal.tsd-is-private > .tsd-kind-icon:before { background-position: -34px -17px; }
|
||||
|
||||
.tsd-kind-class > .tsd-kind-icon:before { background-position: 0px -34px; }
|
||||
.tsd-kind-class.tsd-is-protected > .tsd-kind-icon:before { background-position: -17px -34px; }
|
||||
.tsd-kind-class.tsd-is-private > .tsd-kind-icon:before { background-position: -34px -34px; }
|
||||
|
||||
.tsd-kind-class.tsd-has-type-parameter > .tsd-kind-icon:before { background-position: 0px -51px; }
|
||||
.tsd-kind-class.tsd-has-type-parameter.tsd-is-protected > .tsd-kind-icon:before { background-position: -17px -51px; }
|
||||
.tsd-kind-class.tsd-has-type-parameter.tsd-is-private > .tsd-kind-icon:before { background-position: -34px -51px; }
|
||||
|
||||
.tsd-kind-interface > .tsd-kind-icon:before { background-position: 0px -68px; }
|
||||
.tsd-kind-interface.tsd-is-protected > .tsd-kind-icon:before { background-position: -17px -68px; }
|
||||
.tsd-kind-interface.tsd-is-private > .tsd-kind-icon:before { background-position: -34px -68px; }
|
||||
|
||||
.tsd-kind-interface.tsd-has-type-parameter > .tsd-kind-icon:before { background-position: 0px -85px; }
|
||||
.tsd-kind-interface.tsd-has-type-parameter.tsd-is-protected > .tsd-kind-icon:before { background-position: -17px -85px; }
|
||||
.tsd-kind-interface.tsd-has-type-parameter.tsd-is-private > .tsd-kind-icon:before { background-position: -34px -85px; }
|
||||
|
||||
.tsd-kind-module > .tsd-kind-icon:before { background-position: 0px -102px; }
|
||||
.tsd-kind-module.tsd-is-protected > .tsd-kind-icon:before { background-position: -17px -102px; }
|
||||
.tsd-kind-module.tsd-is-private > .tsd-kind-icon:before { background-position: -34px -102px; }
|
||||
|
||||
.tsd-kind-external-module > .tsd-kind-icon:before { background-position: 0px -102px; }
|
||||
.tsd-kind-external-module.tsd-is-protected > .tsd-kind-icon:before { background-position: -17px -102px; }
|
||||
.tsd-kind-external-module.tsd-is-private > .tsd-kind-icon:before { background-position: -34px -102px; }
|
||||
|
||||
.tsd-kind-enum > .tsd-kind-icon:before { background-position: 0px -119px; }
|
||||
.tsd-kind-enum.tsd-is-protected > .tsd-kind-icon:before { background-position: -17px -119px; }
|
||||
.tsd-kind-enum.tsd-is-private > .tsd-kind-icon:before { background-position: -34px -119px; }
|
||||
|
||||
.tsd-kind-enum-member > .tsd-kind-icon:before { background-position: 0px -136px; }
|
||||
.tsd-kind-enum-member.tsd-is-protected > .tsd-kind-icon:before { background-position: -17px -136px; }
|
||||
.tsd-kind-enum-member.tsd-is-private > .tsd-kind-icon:before { background-position: -34px -136px; }
|
||||
|
||||
.tsd-kind-signature > .tsd-kind-icon:before { background-position: 0px -153px; }
|
||||
.tsd-kind-signature.tsd-is-protected > .tsd-kind-icon:before { background-position: -17px -153px; }
|
||||
.tsd-kind-signature.tsd-is-private > .tsd-kind-icon:before { background-position: -34px -153px; }
|
||||
|
||||
.tsd-kind-type-alias > .tsd-kind-icon:before { background-position: 0px -170px; }
|
||||
.tsd-kind-type-alias.tsd-is-protected > .tsd-kind-icon:before { background-position: -17px -170px; }
|
||||
.tsd-kind-type-alias.tsd-is-private > .tsd-kind-icon:before { background-position: -34px -170px; }
|
||||
|
||||
.tsd-kind-variable > .tsd-kind-icon:before { background-position: -136px -0px; }
|
||||
.tsd-kind-variable.tsd-is-protected > .tsd-kind-icon:before { background-position: -153px -0px; }
|
||||
.tsd-kind-variable.tsd-is-private > .tsd-kind-icon:before { background-position: -119px -0px; }
|
||||
.tsd-kind-variable.tsd-parent-kind-class > .tsd-kind-icon:before { background-position: -51px -0px; }
|
||||
.tsd-kind-variable.tsd-parent-kind-class.tsd-is-inherited > .tsd-kind-icon:before { background-position: -68px -0px; }
|
||||
.tsd-kind-variable.tsd-parent-kind-class.tsd-is-protected > .tsd-kind-icon:before { background-position: -85px -0px; }
|
||||
.tsd-kind-variable.tsd-parent-kind-class.tsd-is-protected.tsd-is-inherited > .tsd-kind-icon:before { background-position: -102px -0px; }
|
||||
.tsd-kind-variable.tsd-parent-kind-class.tsd-is-private > .tsd-kind-icon:before { background-position: -119px -0px; }
|
||||
.tsd-kind-variable.tsd-parent-kind-enum > .tsd-kind-icon:before { background-position: -170px -0px; }
|
||||
.tsd-kind-variable.tsd-parent-kind-enum.tsd-is-protected > .tsd-kind-icon:before { background-position: -187px -0px; }
|
||||
.tsd-kind-variable.tsd-parent-kind-enum.tsd-is-private > .tsd-kind-icon:before { background-position: -119px -0px; }
|
||||
.tsd-kind-variable.tsd-parent-kind-interface > .tsd-kind-icon:before { background-position: -204px -0px; }
|
||||
.tsd-kind-variable.tsd-parent-kind-interface.tsd-is-inherited > .tsd-kind-icon:before { background-position: -221px -0px; }
|
||||
|
||||
.tsd-kind-property > .tsd-kind-icon:before { background-position: -136px -0px; }
|
||||
.tsd-kind-property.tsd-is-protected > .tsd-kind-icon:before { background-position: -153px -0px; }
|
||||
.tsd-kind-property.tsd-is-private > .tsd-kind-icon:before { background-position: -119px -0px; }
|
||||
.tsd-kind-property.tsd-parent-kind-class > .tsd-kind-icon:before { background-position: -51px -0px; }
|
||||
.tsd-kind-property.tsd-parent-kind-class.tsd-is-inherited > .tsd-kind-icon:before { background-position: -68px -0px; }
|
||||
.tsd-kind-property.tsd-parent-kind-class.tsd-is-protected > .tsd-kind-icon:before { background-position: -85px -0px; }
|
||||
.tsd-kind-property.tsd-parent-kind-class.tsd-is-protected.tsd-is-inherited > .tsd-kind-icon:before { background-position: -102px -0px; }
|
||||
.tsd-kind-property.tsd-parent-kind-class.tsd-is-private > .tsd-kind-icon:before { background-position: -119px -0px; }
|
||||
.tsd-kind-property.tsd-parent-kind-enum > .tsd-kind-icon:before { background-position: -170px -0px; }
|
||||
.tsd-kind-property.tsd-parent-kind-enum.tsd-is-protected > .tsd-kind-icon:before { background-position: -187px -0px; }
|
||||
.tsd-kind-property.tsd-parent-kind-enum.tsd-is-private > .tsd-kind-icon:before { background-position: -119px -0px; }
|
||||
.tsd-kind-property.tsd-parent-kind-interface > .tsd-kind-icon:before { background-position: -204px -0px; }
|
||||
.tsd-kind-property.tsd-parent-kind-interface.tsd-is-inherited > .tsd-kind-icon:before { background-position: -221px -0px; }
|
||||
|
||||
.tsd-kind-get-signature > .tsd-kind-icon:before { background-position: -136px -17px; }
|
||||
.tsd-kind-get-signature.tsd-is-protected > .tsd-kind-icon:before { background-position: -153px -17px; }
|
||||
.tsd-kind-get-signature.tsd-is-private > .tsd-kind-icon:before { background-position: -119px -17px; }
|
||||
.tsd-kind-get-signature.tsd-parent-kind-class > .tsd-kind-icon:before { background-position: -51px -17px; }
|
||||
.tsd-kind-get-signature.tsd-parent-kind-class.tsd-is-inherited > .tsd-kind-icon:before { background-position: -68px -17px; }
|
||||
.tsd-kind-get-signature.tsd-parent-kind-class.tsd-is-protected > .tsd-kind-icon:before { background-position: -85px -17px; }
|
||||
.tsd-kind-get-signature.tsd-parent-kind-class.tsd-is-protected.tsd-is-inherited > .tsd-kind-icon:before { background-position: -102px -17px; }
|
||||
.tsd-kind-get-signature.tsd-parent-kind-class.tsd-is-private > .tsd-kind-icon:before { background-position: -119px -17px; }
|
||||
.tsd-kind-get-signature.tsd-parent-kind-enum > .tsd-kind-icon:before { background-position: -170px -17px; }
|
||||
.tsd-kind-get-signature.tsd-parent-kind-enum.tsd-is-protected > .tsd-kind-icon:before { background-position: -187px -17px; }
|
||||
.tsd-kind-get-signature.tsd-parent-kind-enum.tsd-is-private > .tsd-kind-icon:before { background-position: -119px -17px; }
|
||||
.tsd-kind-get-signature.tsd-parent-kind-interface > .tsd-kind-icon:before { background-position: -204px -17px; }
|
||||
.tsd-kind-get-signature.tsd-parent-kind-interface.tsd-is-inherited > .tsd-kind-icon:before { background-position: -221px -17px; }
|
||||
|
||||
.tsd-kind-set-signature > .tsd-kind-icon:before { background-position: -136px -34px; }
|
||||
.tsd-kind-set-signature.tsd-is-protected > .tsd-kind-icon:before { background-position: -153px -34px; }
|
||||
.tsd-kind-set-signature.tsd-is-private > .tsd-kind-icon:before { background-position: -119px -34px; }
|
||||
.tsd-kind-set-signature.tsd-parent-kind-class > .tsd-kind-icon:before { background-position: -51px -34px; }
|
||||
.tsd-kind-set-signature.tsd-parent-kind-class.tsd-is-inherited > .tsd-kind-icon:before { background-position: -68px -34px; }
|
||||
.tsd-kind-set-signature.tsd-parent-kind-class.tsd-is-protected > .tsd-kind-icon:before { background-position: -85px -34px; }
|
||||
.tsd-kind-set-signature.tsd-parent-kind-class.tsd-is-protected.tsd-is-inherited > .tsd-kind-icon:before { background-position: -102px -34px; }
|
||||
.tsd-kind-set-signature.tsd-parent-kind-class.tsd-is-private > .tsd-kind-icon:before { background-position: -119px -34px; }
|
||||
.tsd-kind-set-signature.tsd-parent-kind-enum > .tsd-kind-icon:before { background-position: -170px -34px; }
|
||||
.tsd-kind-set-signature.tsd-parent-kind-enum.tsd-is-protected > .tsd-kind-icon:before { background-position: -187px -34px; }
|
||||
.tsd-kind-set-signature.tsd-parent-kind-enum.tsd-is-private > .tsd-kind-icon:before { background-position: -119px -34px; }
|
||||
.tsd-kind-set-signature.tsd-parent-kind-interface > .tsd-kind-icon:before { background-position: -204px -34px; }
|
||||
.tsd-kind-set-signature.tsd-parent-kind-interface.tsd-is-inherited > .tsd-kind-icon:before { background-position: -221px -34px; }
|
||||
|
||||
.tsd-kind-accessor > .tsd-kind-icon:before { background-position: -136px -51px; }
|
||||
.tsd-kind-accessor.tsd-is-protected > .tsd-kind-icon:before { background-position: -153px -51px; }
|
||||
.tsd-kind-accessor.tsd-is-private > .tsd-kind-icon:before { background-position: -119px -51px; }
|
||||
.tsd-kind-accessor.tsd-parent-kind-class > .tsd-kind-icon:before { background-position: -51px -51px; }
|
||||
.tsd-kind-accessor.tsd-parent-kind-class.tsd-is-inherited > .tsd-kind-icon:before { background-position: -68px -51px; }
|
||||
.tsd-kind-accessor.tsd-parent-kind-class.tsd-is-protected > .tsd-kind-icon:before { background-position: -85px -51px; }
|
||||
.tsd-kind-accessor.tsd-parent-kind-class.tsd-is-protected.tsd-is-inherited > .tsd-kind-icon:before { background-position: -102px -51px; }
|
||||
.tsd-kind-accessor.tsd-parent-kind-class.tsd-is-private > .tsd-kind-icon:before { background-position: -119px -51px; }
|
||||
.tsd-kind-accessor.tsd-parent-kind-enum > .tsd-kind-icon:before { background-position: -170px -51px; }
|
||||
.tsd-kind-accessor.tsd-parent-kind-enum.tsd-is-protected > .tsd-kind-icon:before { background-position: -187px -51px; }
|
||||
.tsd-kind-accessor.tsd-parent-kind-enum.tsd-is-private > .tsd-kind-icon:before { background-position: -119px -51px; }
|
||||
.tsd-kind-accessor.tsd-parent-kind-interface > .tsd-kind-icon:before { background-position: -204px -51px; }
|
||||
.tsd-kind-accessor.tsd-parent-kind-interface.tsd-is-inherited > .tsd-kind-icon:before { background-position: -221px -51px; }
|
||||
|
||||
.tsd-kind-function > .tsd-kind-icon:before { background-position: -136px -68px; }
|
||||
.tsd-kind-function.tsd-is-protected > .tsd-kind-icon:before { background-position: -153px -68px; }
|
||||
.tsd-kind-function.tsd-is-private > .tsd-kind-icon:before { background-position: -119px -68px; }
|
||||
.tsd-kind-function.tsd-parent-kind-class > .tsd-kind-icon:before { background-position: -51px -68px; }
|
||||
.tsd-kind-function.tsd-parent-kind-class.tsd-is-inherited > .tsd-kind-icon:before { background-position: -68px -68px; }
|
||||
.tsd-kind-function.tsd-parent-kind-class.tsd-is-protected > .tsd-kind-icon:before { background-position: -85px -68px; }
|
||||
.tsd-kind-function.tsd-parent-kind-class.tsd-is-protected.tsd-is-inherited > .tsd-kind-icon:before { background-position: -102px -68px; }
|
||||
.tsd-kind-function.tsd-parent-kind-class.tsd-is-private > .tsd-kind-icon:before { background-position: -119px -68px; }
|
||||
.tsd-kind-function.tsd-parent-kind-enum > .tsd-kind-icon:before { background-position: -170px -68px; }
|
||||
.tsd-kind-function.tsd-parent-kind-enum.tsd-is-protected > .tsd-kind-icon:before { background-position: -187px -68px; }
|
||||
.tsd-kind-function.tsd-parent-kind-enum.tsd-is-private > .tsd-kind-icon:before { background-position: -119px -68px; }
|
||||
.tsd-kind-function.tsd-parent-kind-interface > .tsd-kind-icon:before { background-position: -204px -68px; }
|
||||
.tsd-kind-function.tsd-parent-kind-interface.tsd-is-inherited > .tsd-kind-icon:before { background-position: -221px -68px; }
|
||||
|
||||
.tsd-kind-method > .tsd-kind-icon:before { background-position: -136px -68px; }
|
||||
.tsd-kind-method.tsd-is-protected > .tsd-kind-icon:before { background-position: -153px -68px; }
|
||||
.tsd-kind-method.tsd-is-private > .tsd-kind-icon:before { background-position: -119px -68px; }
|
||||
.tsd-kind-method.tsd-parent-kind-class > .tsd-kind-icon:before { background-position: -51px -68px; }
|
||||
.tsd-kind-method.tsd-parent-kind-class.tsd-is-inherited > .tsd-kind-icon:before { background-position: -68px -68px; }
|
||||
.tsd-kind-method.tsd-parent-kind-class.tsd-is-protected > .tsd-kind-icon:before { background-position: -85px -68px; }
|
||||
.tsd-kind-method.tsd-parent-kind-class.tsd-is-protected.tsd-is-inherited > .tsd-kind-icon:before { background-position: -102px -68px; }
|
||||
.tsd-kind-method.tsd-parent-kind-class.tsd-is-private > .tsd-kind-icon:before { background-position: -119px -68px; }
|
||||
.tsd-kind-method.tsd-parent-kind-enum > .tsd-kind-icon:before { background-position: -170px -68px; }
|
||||
.tsd-kind-method.tsd-parent-kind-enum.tsd-is-protected > .tsd-kind-icon:before { background-position: -187px -68px; }
|
||||
.tsd-kind-method.tsd-parent-kind-enum.tsd-is-private > .tsd-kind-icon:before { background-position: -119px -68px; }
|
||||
.tsd-kind-method.tsd-parent-kind-interface > .tsd-kind-icon:before { background-position: -204px -68px; }
|
||||
.tsd-kind-method.tsd-parent-kind-interface.tsd-is-inherited > .tsd-kind-icon:before { background-position: -221px -68px; }
|
||||
|
||||
.tsd-kind-call-signature > .tsd-kind-icon:before { background-position: -136px -68px; }
|
||||
.tsd-kind-call-signature.tsd-is-protected > .tsd-kind-icon:before { background-position: -153px -68px; }
|
||||
.tsd-kind-call-signature.tsd-is-private > .tsd-kind-icon:before { background-position: -119px -68px; }
|
||||
.tsd-kind-call-signature.tsd-parent-kind-class > .tsd-kind-icon:before { background-position: -51px -68px; }
|
||||
.tsd-kind-call-signature.tsd-parent-kind-class.tsd-is-inherited > .tsd-kind-icon:before { background-position: -68px -68px; }
|
||||
.tsd-kind-call-signature.tsd-parent-kind-class.tsd-is-protected > .tsd-kind-icon:before { background-position: -85px -68px; }
|
||||
.tsd-kind-call-signature.tsd-parent-kind-class.tsd-is-protected.tsd-is-inherited > .tsd-kind-icon:before { background-position: -102px -68px; }
|
||||
.tsd-kind-call-signature.tsd-parent-kind-class.tsd-is-private > .tsd-kind-icon:before { background-position: -119px -68px; }
|
||||
.tsd-kind-call-signature.tsd-parent-kind-enum > .tsd-kind-icon:before { background-position: -170px -68px; }
|
||||
.tsd-kind-call-signature.tsd-parent-kind-enum.tsd-is-protected > .tsd-kind-icon:before { background-position: -187px -68px; }
|
||||
.tsd-kind-call-signature.tsd-parent-kind-enum.tsd-is-private > .tsd-kind-icon:before { background-position: -119px -68px; }
|
||||
.tsd-kind-call-signature.tsd-parent-kind-interface > .tsd-kind-icon:before { background-position: -204px -68px; }
|
||||
.tsd-kind-call-signature.tsd-parent-kind-interface.tsd-is-inherited > .tsd-kind-icon:before { background-position: -221px -68px; }
|
||||
|
||||
.tsd-kind-function.tsd-has-type-parameter > .tsd-kind-icon:before { background-position: -136px -85px; }
|
||||
.tsd-kind-function.tsd-has-type-parameter.tsd-is-protected > .tsd-kind-icon:before { background-position: -153px -85px; }
|
||||
.tsd-kind-function.tsd-has-type-parameter.tsd-is-private > .tsd-kind-icon:before { background-position: -119px -85px; }
|
||||
.tsd-kind-function.tsd-has-type-parameter.tsd-parent-kind-class > .tsd-kind-icon:before { background-position: -51px -85px; }
|
||||
.tsd-kind-function.tsd-has-type-parameter.tsd-parent-kind-class.tsd-is-inherited > .tsd-kind-icon:before { background-position: -68px -85px; }
|
||||
.tsd-kind-function.tsd-has-type-parameter.tsd-parent-kind-class.tsd-is-protected > .tsd-kind-icon:before { background-position: -85px -85px; }
|
||||
.tsd-kind-function.tsd-has-type-parameter.tsd-parent-kind-class.tsd-is-protected.tsd-is-inherited > .tsd-kind-icon:before { background-position: -102px -85px; }
|
||||
.tsd-kind-function.tsd-has-type-parameter.tsd-parent-kind-class.tsd-is-private > .tsd-kind-icon:before { background-position: -119px -85px; }
|
||||
.tsd-kind-function.tsd-has-type-parameter.tsd-parent-kind-enum > .tsd-kind-icon:before { background-position: -170px -85px; }
|
||||
.tsd-kind-function.tsd-has-type-parameter.tsd-parent-kind-enum.tsd-is-protected > .tsd-kind-icon:before { background-position: -187px -85px; }
|
||||
.tsd-kind-function.tsd-has-type-parameter.tsd-parent-kind-enum.tsd-is-private > .tsd-kind-icon:before { background-position: -119px -85px; }
|
||||
.tsd-kind-function.tsd-has-type-parameter.tsd-parent-kind-interface > .tsd-kind-icon:before { background-position: -204px -85px; }
|
||||
.tsd-kind-function.tsd-has-type-parameter.tsd-parent-kind-interface.tsd-is-inherited > .tsd-kind-icon:before { background-position: -221px -85px; }
|
||||
|
||||
.tsd-kind-method.tsd-has-type-parameter > .tsd-kind-icon:before { background-position: -136px -85px; }
|
||||
.tsd-kind-method.tsd-has-type-parameter.tsd-is-protected > .tsd-kind-icon:before { background-position: -153px -85px; }
|
||||
.tsd-kind-method.tsd-has-type-parameter.tsd-is-private > .tsd-kind-icon:before { background-position: -119px -85px; }
|
||||
.tsd-kind-method.tsd-has-type-parameter.tsd-parent-kind-class > .tsd-kind-icon:before { background-position: -51px -85px; }
|
||||
.tsd-kind-method.tsd-has-type-parameter.tsd-parent-kind-class.tsd-is-inherited > .tsd-kind-icon:before { background-position: -68px -85px; }
|
||||
.tsd-kind-method.tsd-has-type-parameter.tsd-parent-kind-class.tsd-is-protected > .tsd-kind-icon:before { background-position: -85px -85px; }
|
||||
.tsd-kind-method.tsd-has-type-parameter.tsd-parent-kind-class.tsd-is-protected.tsd-is-inherited > .tsd-kind-icon:before { background-position: -102px -85px; }
|
||||
.tsd-kind-method.tsd-has-type-parameter.tsd-parent-kind-class.tsd-is-private > .tsd-kind-icon:before { background-position: -119px -85px; }
|
||||
.tsd-kind-method.tsd-has-type-parameter.tsd-parent-kind-enum > .tsd-kind-icon:before { background-position: -170px -85px; }
|
||||
.tsd-kind-method.tsd-has-type-parameter.tsd-parent-kind-enum.tsd-is-protected > .tsd-kind-icon:before { background-position: -187px -85px; }
|
||||
.tsd-kind-method.tsd-has-type-parameter.tsd-parent-kind-enum.tsd-is-private > .tsd-kind-icon:before { background-position: -119px -85px; }
|
||||
.tsd-kind-method.tsd-has-type-parameter.tsd-parent-kind-interface > .tsd-kind-icon:before { background-position: -204px -85px; }
|
||||
.tsd-kind-method.tsd-has-type-parameter.tsd-parent-kind-interface.tsd-is-inherited > .tsd-kind-icon:before { background-position: -221px -85px; }
|
||||
|
||||
.tsd-kind-constructor > .tsd-kind-icon:before { background-position: -136px -102px; }
|
||||
.tsd-kind-constructor.tsd-is-protected > .tsd-kind-icon:before { background-position: -153px -102px; }
|
||||
.tsd-kind-constructor.tsd-is-private > .tsd-kind-icon:before { background-position: -119px -102px; }
|
||||
.tsd-kind-constructor.tsd-parent-kind-class > .tsd-kind-icon:before { background-position: -51px -102px; }
|
||||
.tsd-kind-constructor.tsd-parent-kind-class.tsd-is-inherited > .tsd-kind-icon:before { background-position: -68px -102px; }
|
||||
.tsd-kind-constructor.tsd-parent-kind-class.tsd-is-protected > .tsd-kind-icon:before { background-position: -85px -102px; }
|
||||
.tsd-kind-constructor.tsd-parent-kind-class.tsd-is-protected.tsd-is-inherited > .tsd-kind-icon:before { background-position: -102px -102px; }
|
||||
.tsd-kind-constructor.tsd-parent-kind-class.tsd-is-private > .tsd-kind-icon:before { background-position: -119px -102px; }
|
||||
.tsd-kind-constructor.tsd-parent-kind-enum > .tsd-kind-icon:before { background-position: -170px -102px; }
|
||||
.tsd-kind-constructor.tsd-parent-kind-enum.tsd-is-protected > .tsd-kind-icon:before { background-position: -187px -102px; }
|
||||
.tsd-kind-constructor.tsd-parent-kind-enum.tsd-is-private > .tsd-kind-icon:before { background-position: -119px -102px; }
|
||||
.tsd-kind-constructor.tsd-parent-kind-interface > .tsd-kind-icon:before { background-position: -204px -102px; }
|
||||
.tsd-kind-constructor.tsd-parent-kind-interface.tsd-is-inherited > .tsd-kind-icon:before { background-position: -221px -102px; }
|
||||
|
||||
.tsd-kind-constructor-signature > .tsd-kind-icon:before { background-position: -136px -102px; }
|
||||
.tsd-kind-constructor-signature.tsd-is-protected > .tsd-kind-icon:before { background-position: -153px -102px; }
|
||||
.tsd-kind-constructor-signature.tsd-is-private > .tsd-kind-icon:before { background-position: -119px -102px; }
|
||||
.tsd-kind-constructor-signature.tsd-parent-kind-class > .tsd-kind-icon:before { background-position: -51px -102px; }
|
||||
.tsd-kind-constructor-signature.tsd-parent-kind-class.tsd-is-inherited > .tsd-kind-icon:before { background-position: -68px -102px; }
|
||||
.tsd-kind-constructor-signature.tsd-parent-kind-class.tsd-is-protected > .tsd-kind-icon:before { background-position: -85px -102px; }
|
||||
.tsd-kind-constructor-signature.tsd-parent-kind-class.tsd-is-protected.tsd-is-inherited > .tsd-kind-icon:before { background-position: -102px -102px; }
|
||||
.tsd-kind-constructor-signature.tsd-parent-kind-class.tsd-is-private > .tsd-kind-icon:before { background-position: -119px -102px; }
|
||||
.tsd-kind-constructor-signature.tsd-parent-kind-enum > .tsd-kind-icon:before { background-position: -170px -102px; }
|
||||
.tsd-kind-constructor-signature.tsd-parent-kind-enum.tsd-is-protected > .tsd-kind-icon:before { background-position: -187px -102px; }
|
||||
.tsd-kind-constructor-signature.tsd-parent-kind-enum.tsd-is-private > .tsd-kind-icon:before { background-position: -119px -102px; }
|
||||
.tsd-kind-constructor-signature.tsd-parent-kind-interface > .tsd-kind-icon:before { background-position: -204px -102px; }
|
||||
.tsd-kind-constructor-signature.tsd-parent-kind-interface.tsd-is-inherited > .tsd-kind-icon:before { background-position: -221px -102px; }
|
||||
|
||||
.tsd-kind-index-signature > .tsd-kind-icon:before { background-position: -136px -119px; }
|
||||
.tsd-kind-index-signature.tsd-is-protected > .tsd-kind-icon:before { background-position: -153px -119px; }
|
||||
.tsd-kind-index-signature.tsd-is-private > .tsd-kind-icon:before { background-position: -119px -119px; }
|
||||
.tsd-kind-index-signature.tsd-parent-kind-class > .tsd-kind-icon:before { background-position: -51px -119px; }
|
||||
.tsd-kind-index-signature.tsd-parent-kind-class.tsd-is-inherited > .tsd-kind-icon:before { background-position: -68px -119px; }
|
||||
.tsd-kind-index-signature.tsd-parent-kind-class.tsd-is-protected > .tsd-kind-icon:before { background-position: -85px -119px; }
|
||||
.tsd-kind-index-signature.tsd-parent-kind-class.tsd-is-protected.tsd-is-inherited > .tsd-kind-icon:before { background-position: -102px -119px; }
|
||||
.tsd-kind-index-signature.tsd-parent-kind-class.tsd-is-private > .tsd-kind-icon:before { background-position: -119px -119px; }
|
||||
.tsd-kind-index-signature.tsd-parent-kind-enum > .tsd-kind-icon:before { background-position: -170px -119px; }
|
||||
.tsd-kind-index-signature.tsd-parent-kind-enum.tsd-is-protected > .tsd-kind-icon:before { background-position: -187px -119px; }
|
||||
.tsd-kind-index-signature.tsd-parent-kind-enum.tsd-is-private > .tsd-kind-icon:before { background-position: -119px -119px; }
|
||||
.tsd-kind-index-signature.tsd-parent-kind-interface > .tsd-kind-icon:before { background-position: -204px -119px; }
|
||||
.tsd-kind-index-signature.tsd-parent-kind-interface.tsd-is-inherited > .tsd-kind-icon:before { background-position: -221px -119px; }
|
||||
|
||||
.tsd-kind-event > .tsd-kind-icon:before { background-position: -136px -136px; }
|
||||
.tsd-kind-event.tsd-is-protected > .tsd-kind-icon:before { background-position: -153px -136px; }
|
||||
.tsd-kind-event.tsd-is-private > .tsd-kind-icon:before { background-position: -119px -136px; }
|
||||
.tsd-kind-event.tsd-parent-kind-class > .tsd-kind-icon:before { background-position: -51px -136px; }
|
||||
.tsd-kind-event.tsd-parent-kind-class.tsd-is-inherited > .tsd-kind-icon:before { background-position: -68px -136px; }
|
||||
.tsd-kind-event.tsd-parent-kind-class.tsd-is-protected > .tsd-kind-icon:before { background-position: -85px -136px; }
|
||||
.tsd-kind-event.tsd-parent-kind-class.tsd-is-protected.tsd-is-inherited > .tsd-kind-icon:before { background-position: -102px -136px; }
|
||||
.tsd-kind-event.tsd-parent-kind-class.tsd-is-private > .tsd-kind-icon:before { background-position: -119px -136px; }
|
||||
.tsd-kind-event.tsd-parent-kind-enum > .tsd-kind-icon:before { background-position: -170px -136px; }
|
||||
.tsd-kind-event.tsd-parent-kind-enum.tsd-is-protected > .tsd-kind-icon:before { background-position: -187px -136px; }
|
||||
.tsd-kind-event.tsd-parent-kind-enum.tsd-is-private > .tsd-kind-icon:before { background-position: -119px -136px; }
|
||||
.tsd-kind-event.tsd-parent-kind-interface > .tsd-kind-icon:before { background-position: -204px -136px; }
|
||||
.tsd-kind-event.tsd-parent-kind-interface.tsd-is-inherited > .tsd-kind-icon:before { background-position: -221px -136px; }
|
||||
|
||||
.tsd-is-static > .tsd-kind-icon:before { background-position: -136px -153px; }
|
||||
.tsd-is-static.tsd-is-protected > .tsd-kind-icon:before { background-position: -153px -153px; }
|
||||
.tsd-is-static.tsd-is-private > .tsd-kind-icon:before { background-position: -119px -153px; }
|
||||
.tsd-is-static.tsd-parent-kind-class > .tsd-kind-icon:before { background-position: -51px -153px; }
|
||||
.tsd-is-static.tsd-parent-kind-class.tsd-is-inherited > .tsd-kind-icon:before { background-position: -68px -153px; }
|
||||
.tsd-is-static.tsd-parent-kind-class.tsd-is-protected > .tsd-kind-icon:before { background-position: -85px -153px; }
|
||||
.tsd-is-static.tsd-parent-kind-class.tsd-is-protected.tsd-is-inherited > .tsd-kind-icon:before { background-position: -102px -153px; }
|
||||
.tsd-is-static.tsd-parent-kind-class.tsd-is-private > .tsd-kind-icon:before { background-position: -119px -153px; }
|
||||
.tsd-is-static.tsd-parent-kind-enum > .tsd-kind-icon:before { background-position: -170px -153px; }
|
||||
.tsd-is-static.tsd-parent-kind-enum.tsd-is-protected > .tsd-kind-icon:before { background-position: -187px -153px; }
|
||||
.tsd-is-static.tsd-parent-kind-enum.tsd-is-private > .tsd-kind-icon:before { background-position: -119px -153px; }
|
||||
.tsd-is-static.tsd-parent-kind-interface > .tsd-kind-icon:before { background-position: -204px -153px; }
|
||||
.tsd-is-static.tsd-parent-kind-interface.tsd-is-inherited > .tsd-kind-icon:before { background-position: -221px -153px; }
|
||||
|
||||
.tsd-is-static.tsd-kind-function > .tsd-kind-icon:before { background-position: -136px -170px; }
|
||||
.tsd-is-static.tsd-kind-function.tsd-is-protected > .tsd-kind-icon:before { background-position: -153px -170px; }
|
||||
.tsd-is-static.tsd-kind-function.tsd-is-private > .tsd-kind-icon:before { background-position: -119px -170px; }
|
||||
.tsd-is-static.tsd-kind-function.tsd-parent-kind-class > .tsd-kind-icon:before { background-position: -51px -170px; }
|
||||
.tsd-is-static.tsd-kind-function.tsd-parent-kind-class.tsd-is-inherited > .tsd-kind-icon:before { background-position: -68px -170px; }
|
||||
.tsd-is-static.tsd-kind-function.tsd-parent-kind-class.tsd-is-protected > .tsd-kind-icon:before { background-position: -85px -170px; }
|
||||
.tsd-is-static.tsd-kind-function.tsd-parent-kind-class.tsd-is-protected.tsd-is-inherited > .tsd-kind-icon:before { background-position: -102px -170px; }
|
||||
.tsd-is-static.tsd-kind-function.tsd-parent-kind-class.tsd-is-private > .tsd-kind-icon:before { background-position: -119px -170px; }
|
||||
.tsd-is-static.tsd-kind-function.tsd-parent-kind-enum > .tsd-kind-icon:before { background-position: -170px -170px; }
|
||||
.tsd-is-static.tsd-kind-function.tsd-parent-kind-enum.tsd-is-protected > .tsd-kind-icon:before { background-position: -187px -170px; }
|
||||
.tsd-is-static.tsd-kind-function.tsd-parent-kind-enum.tsd-is-private > .tsd-kind-icon:before { background-position: -119px -170px; }
|
||||
.tsd-is-static.tsd-kind-function.tsd-parent-kind-interface > .tsd-kind-icon:before { background-position: -204px -170px; }
|
||||
.tsd-is-static.tsd-kind-function.tsd-parent-kind-interface.tsd-is-inherited > .tsd-kind-icon:before { background-position: -221px -170px; }
|
||||
|
||||
.tsd-is-static.tsd-kind-method > .tsd-kind-icon:before { background-position: -136px -170px; }
|
||||
.tsd-is-static.tsd-kind-method.tsd-is-protected > .tsd-kind-icon:before { background-position: -153px -170px; }
|
||||
.tsd-is-static.tsd-kind-method.tsd-is-private > .tsd-kind-icon:before { background-position: -119px -170px; }
|
||||
.tsd-is-static.tsd-kind-method.tsd-parent-kind-class > .tsd-kind-icon:before { background-position: -51px -170px; }
|
||||
.tsd-is-static.tsd-kind-method.tsd-parent-kind-class.tsd-is-inherited > .tsd-kind-icon:before { background-position: -68px -170px; }
|
||||
.tsd-is-static.tsd-kind-method.tsd-parent-kind-class.tsd-is-protected > .tsd-kind-icon:before { background-position: -85px -170px; }
|
||||
.tsd-is-static.tsd-kind-method.tsd-parent-kind-class.tsd-is-protected.tsd-is-inherited > .tsd-kind-icon:before { background-position: -102px -170px; }
|
||||
.tsd-is-static.tsd-kind-method.tsd-parent-kind-class.tsd-is-private > .tsd-kind-icon:before { background-position: -119px -170px; }
|
||||
.tsd-is-static.tsd-kind-method.tsd-parent-kind-enum > .tsd-kind-icon:before { background-position: -170px -170px; }
|
||||
.tsd-is-static.tsd-kind-method.tsd-parent-kind-enum.tsd-is-protected > .tsd-kind-icon:before { background-position: -187px -170px; }
|
||||
.tsd-is-static.tsd-kind-method.tsd-parent-kind-enum.tsd-is-private > .tsd-kind-icon:before { background-position: -119px -170px; }
|
||||
.tsd-is-static.tsd-kind-method.tsd-parent-kind-interface > .tsd-kind-icon:before { background-position: -204px -170px; }
|
||||
.tsd-is-static.tsd-kind-method.tsd-parent-kind-interface.tsd-is-inherited > .tsd-kind-icon:before { background-position: -221px -170px; }
|
||||
|
||||
.tsd-is-static.tsd-kind-call-signature > .tsd-kind-icon:before { background-position: -136px -170px; }
|
||||
.tsd-is-static.tsd-kind-call-signature.tsd-is-protected > .tsd-kind-icon:before { background-position: -153px -170px; }
|
||||
.tsd-is-static.tsd-kind-call-signature.tsd-is-private > .tsd-kind-icon:before { background-position: -119px -170px; }
|
||||
.tsd-is-static.tsd-kind-call-signature.tsd-parent-kind-class > .tsd-kind-icon:before { background-position: -51px -170px; }
|
||||
.tsd-is-static.tsd-kind-call-signature.tsd-parent-kind-class.tsd-is-inherited > .tsd-kind-icon:before { background-position: -68px -170px; }
|
||||
.tsd-is-static.tsd-kind-call-signature.tsd-parent-kind-class.tsd-is-protected > .tsd-kind-icon:before { background-position: -85px -170px; }
|
||||
.tsd-is-static.tsd-kind-call-signature.tsd-parent-kind-class.tsd-is-protected.tsd-is-inherited > .tsd-kind-icon:before { background-position: -102px -170px; }
|
||||
.tsd-is-static.tsd-kind-call-signature.tsd-parent-kind-class.tsd-is-private > .tsd-kind-icon:before { background-position: -119px -170px; }
|
||||
.tsd-is-static.tsd-kind-call-signature.tsd-parent-kind-enum > .tsd-kind-icon:before { background-position: -170px -170px; }
|
||||
.tsd-is-static.tsd-kind-call-signature.tsd-parent-kind-enum.tsd-is-protected > .tsd-kind-icon:before { background-position: -187px -170px; }
|
||||
.tsd-is-static.tsd-kind-call-signature.tsd-parent-kind-enum.tsd-is-private > .tsd-kind-icon:before { background-position: -119px -170px; }
|
||||
.tsd-is-static.tsd-kind-call-signature.tsd-parent-kind-interface > .tsd-kind-icon:before { background-position: -204px -170px; }
|
||||
.tsd-is-static.tsd-kind-call-signature.tsd-parent-kind-interface.tsd-is-inherited > .tsd-kind-icon:before { background-position: -221px -170px; }
|
||||
|
||||
.tsd-is-static.tsd-kind-event > .tsd-kind-icon:before { background-position: -136px -187px; }
|
||||
.tsd-is-static.tsd-kind-event.tsd-is-protected > .tsd-kind-icon:before { background-position: -153px -187px; }
|
||||
.tsd-is-static.tsd-kind-event.tsd-is-private > .tsd-kind-icon:before { background-position: -119px -187px; }
|
||||
.tsd-is-static.tsd-kind-event.tsd-parent-kind-class > .tsd-kind-icon:before { background-position: -51px -187px; }
|
||||
.tsd-is-static.tsd-kind-event.tsd-parent-kind-class.tsd-is-inherited > .tsd-kind-icon:before { background-position: -68px -187px; }
|
||||
.tsd-is-static.tsd-kind-event.tsd-parent-kind-class.tsd-is-protected > .tsd-kind-icon:before { background-position: -85px -187px; }
|
||||
.tsd-is-static.tsd-kind-event.tsd-parent-kind-class.tsd-is-protected.tsd-is-inherited > .tsd-kind-icon:before { background-position: -102px -187px; }
|
||||
.tsd-is-static.tsd-kind-event.tsd-parent-kind-class.tsd-is-private > .tsd-kind-icon:before { background-position: -119px -187px; }
|
||||
.tsd-is-static.tsd-kind-event.tsd-parent-kind-enum > .tsd-kind-icon:before { background-position: -170px -187px; }
|
||||
.tsd-is-static.tsd-kind-event.tsd-parent-kind-enum.tsd-is-protected > .tsd-kind-icon:before { background-position: -187px -187px; }
|
||||
.tsd-is-static.tsd-kind-event.tsd-parent-kind-enum.tsd-is-private > .tsd-kind-icon:before { background-position: -119px -187px; }
|
||||
.tsd-is-static.tsd-kind-event.tsd-parent-kind-interface > .tsd-kind-icon:before { background-position: -204px -187px; }
|
||||
.tsd-is-static.tsd-kind-event.tsd-parent-kind-interface.tsd-is-inherited > .tsd-kind-icon:before { background-position: -221px -187px; }
|
||||
|
||||
.no-transition { transition: none !important; }
|
||||
|
||||
@-webkit-keyframes fade-in { from { opacity: 0; }
|
||||
to { opacity: 1; } }
|
||||
|
||||
@keyframes fade-in { from { opacity: 0; }
|
||||
to { opacity: 1; } }
|
||||
@-webkit-keyframes fade-out { from { opacity: 1; visibility: visible; }
|
||||
to { opacity: 0; } }
|
||||
@keyframes fade-out { from { opacity: 1; visibility: visible; }
|
||||
to { opacity: 0; } }
|
||||
@-webkit-keyframes fade-in-delayed { 0% { opacity: 0; }
|
||||
33% { opacity: 0; }
|
||||
100% { opacity: 1; } }
|
||||
@keyframes fade-in-delayed { 0% { opacity: 0; }
|
||||
33% { opacity: 0; }
|
||||
100% { opacity: 1; } }
|
||||
@-webkit-keyframes fade-out-delayed { 0% { opacity: 1; visibility: visible; }
|
||||
66% { opacity: 0; }
|
||||
100% { opacity: 0; } }
|
||||
@keyframes fade-out-delayed { 0% { opacity: 1; visibility: visible; }
|
||||
66% { opacity: 0; }
|
||||
100% { opacity: 0; } }
|
||||
@-webkit-keyframes shift-to-left { from { -webkit-transform: translate(0, 0); transform: translate(0, 0); }
|
||||
to { -webkit-transform: translate(-25%, 0); transform: translate(-25%, 0); } }
|
||||
@keyframes shift-to-left { from { -webkit-transform: translate(0, 0); transform: translate(0, 0); }
|
||||
to { -webkit-transform: translate(-25%, 0); transform: translate(-25%, 0); } }
|
||||
@-webkit-keyframes unshift-to-left { from { -webkit-transform: translate(-25%, 0); transform: translate(-25%, 0); }
|
||||
to { -webkit-transform: translate(0, 0); transform: translate(0, 0); } }
|
||||
@keyframes unshift-to-left { from { -webkit-transform: translate(-25%, 0); transform: translate(-25%, 0); }
|
||||
to { -webkit-transform: translate(0, 0); transform: translate(0, 0); } }
|
||||
@-webkit-keyframes pop-in-from-right { from { -webkit-transform: translate(100%, 0); transform: translate(100%, 0); }
|
||||
to { -webkit-transform: translate(0, 0); transform: translate(0, 0); } }
|
||||
@keyframes pop-in-from-right { from { -webkit-transform: translate(100%, 0); transform: translate(100%, 0); }
|
||||
to { -webkit-transform: translate(0, 0); transform: translate(0, 0); } }
|
||||
@-webkit-keyframes pop-out-to-right { from { -webkit-transform: translate(0, 0); transform: translate(0, 0); visibility: visible; }
|
||||
to { -webkit-transform: translate(100%, 0); transform: translate(100%, 0); } }
|
||||
@keyframes pop-out-to-right { from { -webkit-transform: translate(0, 0); transform: translate(0, 0); visibility: visible; }
|
||||
to { -webkit-transform: translate(100%, 0); transform: translate(100%, 0); } }
|
||||
body { background: #fdfdfd; font-family: "Segoe UI", sans-serif; font-size: 16px; color: #222; }
|
||||
|
||||
a { color: #4da6ff; text-decoration: none; }
|
||||
a:hover { text-decoration: underline; }
|
||||
|
||||
code, pre { font-family: Menlo, Monaco, Consolas, "Courier New", monospace; padding: 0.2em; margin: 0; font-size: 14px; background-color: rgba(0, 0, 0, 0.04); }
|
||||
|
||||
pre { padding: 10px; }
|
||||
pre code { padding: 0; font-size: 100%; background-color: transparent; }
|
||||
|
||||
.tsd-typography { line-height: 1.333em; }
|
||||
.tsd-typography ul { list-style: square; padding: 0 0 0 20px; margin: 0; }
|
||||
.tsd-typography h4, .tsd-typography .tsd-index-panel h3, .tsd-index-panel .tsd-typography h3, .tsd-typography h5, .tsd-typography h6 { font-size: 1em; margin: 0; }
|
||||
.tsd-typography h5, .tsd-typography h6 { font-weight: normal; }
|
||||
.tsd-typography p, .tsd-typography ul, .tsd-typography ol { margin: 1em 0; }
|
||||
|
||||
@media (min-width: 901px) and (max-width: 1024px) { html.default .col-content { width: 72%; }
|
||||
html.default .col-menu { width: 28%; }
|
||||
html.default .tsd-navigation { padding-left: 10px; } }
|
||||
@media (max-width: 900px) { html.default .col-content { float: none; width: 100%; }
|
||||
html.default .col-menu { position: fixed !important; overflow: auto; -webkit-overflow-scrolling: touch; overflow-scrolling: touch; z-index: 1024; top: 0 !important; bottom: 0 !important; left: auto !important; right: 0 !important; width: 100%; padding: 20px 20px 0 0; max-width: 450px; visibility: hidden; background-color: #fff; -webkit-transform: translate(100%, 0); transform: translate(100%, 0); }
|
||||
html.default .col-menu > *:last-child { padding-bottom: 20px; }
|
||||
html.default .overlay { content: ""; display: block; position: fixed; z-index: 1023; top: 0; left: 0; right: 0; bottom: 0; background-color: rgba(0, 0, 0, 0.75); visibility: hidden; }
|
||||
html.default.to-has-menu .overlay { -webkit-animation: fade-in 0.4s; animation: fade-in 0.4s; }
|
||||
html.default.to-has-menu header, html.default.to-has-menu footer, html.default.to-has-menu .col-content { -webkit-animation: shift-to-left 0.4s; animation: shift-to-left 0.4s; }
|
||||
html.default.to-has-menu .col-menu { -webkit-animation: pop-in-from-right 0.4s; animation: pop-in-from-right 0.4s; }
|
||||
html.default.from-has-menu .overlay { -webkit-animation: fade-out 0.4s; animation: fade-out 0.4s; }
|
||||
html.default.from-has-menu header, html.default.from-has-menu footer, html.default.from-has-menu .col-content { -webkit-animation: unshift-to-left 0.4s; animation: unshift-to-left 0.4s; }
|
||||
html.default.from-has-menu .col-menu { -webkit-animation: pop-out-to-right 0.4s; animation: pop-out-to-right 0.4s; }
|
||||
html.default.has-menu body { overflow: hidden; }
|
||||
html.default.has-menu .overlay { visibility: visible; }
|
||||
html.default.has-menu header, html.default.has-menu footer, html.default.has-menu .col-content { -webkit-transform: translate(-25%, 0); transform: translate(-25%, 0); }
|
||||
html.default.has-menu .col-menu { visibility: visible; -webkit-transform: translate(0, 0); transform: translate(0, 0); } }
|
||||
|
||||
.tsd-page-title { padding: 70px 0 20px 0; margin: 0 0 40px 0; background: #fff; box-shadow: 0 0 5px rgba(0, 0, 0, 0.35); }
|
||||
.tsd-page-title h1 { margin: 0; }
|
||||
|
||||
.tsd-breadcrumb { margin: 0; padding: 0; color: #808080; }
|
||||
.tsd-breadcrumb a { color: #808080; text-decoration: none; }
|
||||
.tsd-breadcrumb a:hover { text-decoration: underline; }
|
||||
.tsd-breadcrumb li { display: inline; }
|
||||
.tsd-breadcrumb li:after { content: " / "; }
|
||||
|
||||
html.minimal .container { margin: 0; }
|
||||
html.minimal .container-main { padding-top: 50px; padding-bottom: 0; }
|
||||
html.minimal .content-wrap { padding-left: 300px; }
|
||||
html.minimal .tsd-navigation { position: fixed !important; overflow: auto; -webkit-overflow-scrolling: touch; overflow-scrolling: touch; box-sizing: border-box; z-index: 1; left: 0; top: 40px; bottom: 0; width: 300px; padding: 20px; margin: 0; }
|
||||
html.minimal .tsd-member .tsd-member { margin-left: 0; }
|
||||
html.minimal .tsd-page-toolbar { position: fixed; z-index: 2; }
|
||||
html.minimal #tsd-filter .tsd-filter-group { right: 0; -webkit-transform: none; transform: none; }
|
||||
html.minimal footer { background-color: transparent; }
|
||||
html.minimal footer .container { padding: 0; }
|
||||
html.minimal .tsd-generator { padding: 0; }
|
||||
@media (max-width: 900px) { html.minimal .tsd-navigation { display: none; }
|
||||
html.minimal .content-wrap { padding-left: 0; } }
|
||||
|
||||
dl.tsd-comment-tags { overflow: hidden; }
|
||||
dl.tsd-comment-tags dt { clear: both; float: left; padding: 1px 5px; margin: 0 10px 0 0; border-radius: 4px; border: 1px solid #808080; color: #808080; font-size: 0.8em; font-weight: normal; }
|
||||
dl.tsd-comment-tags dd { margin: 0 0 10px 0; }
|
||||
dl.tsd-comment-tags p { margin: 0; }
|
||||
|
||||
.tsd-panel.tsd-comment .lead { font-size: 1.1em; line-height: 1.333em; margin-bottom: 2em; }
|
||||
.tsd-panel.tsd-comment .lead:last-child { margin-bottom: 0; }
|
||||
|
||||
.toggle-protected .tsd-is-private { display: none; }
|
||||
|
||||
.toggle-public .tsd-is-private, .toggle-public .tsd-is-protected, .toggle-public .tsd-is-private-protected { display: none; }
|
||||
|
||||
.toggle-inherited .tsd-is-inherited { display: none; }
|
||||
|
||||
.toggle-only-exported .tsd-is-not-exported { display: none; }
|
||||
|
||||
.toggle-externals .tsd-is-external { display: none; }
|
||||
|
||||
#tsd-filter { position: relative; display: inline-block; height: 40px; vertical-align: bottom; }
|
||||
.no-filter #tsd-filter { display: none; }
|
||||
#tsd-filter .tsd-filter-group { display: inline-block; height: 40px; vertical-align: bottom; white-space: nowrap; }
|
||||
#tsd-filter input { display: none; }
|
||||
@media (max-width: 900px) { #tsd-filter .tsd-filter-group { display: block; position: absolute; top: 40px; right: 20px; height: auto; background-color: #fff; visibility: hidden; -webkit-transform: translate(50%, 0); transform: translate(50%, 0); box-shadow: 0 0 4px rgba(0, 0, 0, 0.25); }
|
||||
.has-options #tsd-filter .tsd-filter-group { visibility: visible; }
|
||||
.to-has-options #tsd-filter .tsd-filter-group { -webkit-animation: fade-in 0.2s; animation: fade-in 0.2s; }
|
||||
.from-has-options #tsd-filter .tsd-filter-group { -webkit-animation: fade-out 0.2s; animation: fade-out 0.2s; }
|
||||
#tsd-filter label, #tsd-filter .tsd-select { display: block; padding-right: 20px; } }
|
||||
|
||||
footer { border-top: 1px solid #eee; background-color: #fff; }
|
||||
footer.with-border-bottom { border-bottom: 1px solid #eee; }
|
||||
footer .tsd-legend-group { font-size: 0; }
|
||||
footer .tsd-legend { display: inline-block; width: 25%; padding: 0; font-size: 16px; list-style: none; line-height: 1.333em; vertical-align: top; }
|
||||
@media (max-width: 900px) { footer .tsd-legend { width: 50%; } }
|
||||
|
||||
.tsd-hierarchy { list-style: square; padding: 0 0 0 20px; margin: 0; }
|
||||
.tsd-hierarchy .target { font-weight: bold; }
|
||||
|
||||
.tsd-index-panel .tsd-index-content { margin-bottom: -30px !important; }
|
||||
.tsd-index-panel .tsd-index-section { margin-bottom: 30px !important; }
|
||||
.tsd-index-panel h3 { margin: 0 -20px 10px -20px; padding: 0 20px 10px 20px; border-bottom: 1px solid #eee; }
|
||||
.tsd-index-panel ul.tsd-index-list { -webkit-column-count: 3; -moz-column-count: 3; -ms-column-count: 3; -o-column-count: 3; column-count: 3; -webkit-column-gap: 20px; -moz-column-gap: 20px; -ms-column-gap: 20px; -o-column-gap: 20px; column-gap: 20px; padding: 0; list-style: none; line-height: 1.333em; }
|
||||
@media (max-width: 900px) { .tsd-index-panel ul.tsd-index-list { -webkit-column-count: 1; -moz-column-count: 1; -ms-column-count: 1; -o-column-count: 1; column-count: 1; } }
|
||||
@media (min-width: 901px) and (max-width: 1024px) { .tsd-index-panel ul.tsd-index-list { -webkit-column-count: 2; -moz-column-count: 2; -ms-column-count: 2; -o-column-count: 2; column-count: 2; } }
|
||||
.tsd-index-panel ul.tsd-index-list li { -webkit-column-break-inside: avoid; -moz-column-break-inside: avoid; -ms-column-break-inside: avoid; -o-column-break-inside: avoid; column-break-inside: avoid; -webkit-page-break-inside: avoid; -moz-page-break-inside: avoid; -ms-page-break-inside: avoid; -o-page-break-inside: avoid; page-break-inside: avoid; }
|
||||
.tsd-index-panel a, .tsd-index-panel .tsd-parent-kind-module a { color: #9600ff; }
|
||||
.tsd-index-panel .tsd-parent-kind-interface a { color: #7da01f; }
|
||||
.tsd-index-panel .tsd-parent-kind-enum a { color: #cc9900; }
|
||||
.tsd-index-panel .tsd-parent-kind-class a { color: #4da6ff; }
|
||||
.tsd-index-panel .tsd-kind-module a { color: #9600ff; }
|
||||
.tsd-index-panel .tsd-kind-interface a { color: #7da01f; }
|
||||
.tsd-index-panel .tsd-kind-enum a { color: #cc9900; }
|
||||
.tsd-index-panel .tsd-kind-class a { color: #4da6ff; }
|
||||
.tsd-index-panel .tsd-is-private a { color: #808080; }
|
||||
|
||||
.tsd-flag { display: inline-block; padding: 1px 5px; border-radius: 4px; color: #fff; background-color: #808080; text-indent: 0; font-size: 14px; font-weight: normal; }
|
||||
|
||||
.tsd-anchor { position: absolute; top: -100px; }
|
||||
|
||||
.tsd-member { position: relative; }
|
||||
.tsd-member .tsd-anchor + h3 { margin-top: 0; margin-bottom: 0; border-bottom: none; }
|
||||
|
||||
.tsd-navigation { padding: 0 0 0 40px; }
|
||||
.tsd-navigation a { display: block; padding-top: 2px; padding-bottom: 2px; border-left: 2px solid transparent; color: #222; text-decoration: none; transition: border-left-color 0.1s; }
|
||||
.tsd-navigation a:hover { text-decoration: underline; }
|
||||
.tsd-navigation ul { margin: 0; padding: 0; list-style: none; }
|
||||
.tsd-navigation li { padding: 0; }
|
||||
|
||||
.tsd-navigation.primary { padding-bottom: 40px; }
|
||||
.tsd-navigation.primary a { display: block; padding-top: 6px; padding-bottom: 6px; }
|
||||
.tsd-navigation.primary ul li a { padding-left: 5px; }
|
||||
.tsd-navigation.primary ul li li a { padding-left: 25px; }
|
||||
.tsd-navigation.primary ul li li li a { padding-left: 45px; }
|
||||
.tsd-navigation.primary ul li li li li a { padding-left: 65px; }
|
||||
.tsd-navigation.primary ul li li li li li a { padding-left: 85px; }
|
||||
.tsd-navigation.primary ul li li li li li li a { padding-left: 105px; }
|
||||
.tsd-navigation.primary > ul { border-bottom: 1px solid #eee; }
|
||||
.tsd-navigation.primary li { border-top: 1px solid #eee; }
|
||||
.tsd-navigation.primary li.current > a { font-weight: bold; }
|
||||
.tsd-navigation.primary li.label span { display: block; padding: 20px 0 6px 5px; color: #808080; }
|
||||
.tsd-navigation.primary li.globals + li > span, .tsd-navigation.primary li.globals + li > a { padding-top: 20px; }
|
||||
|
||||
.tsd-navigation.secondary ul { transition: opacity 0.2s; }
|
||||
.tsd-navigation.secondary ul li a { padding-left: 25px; }
|
||||
.tsd-navigation.secondary ul li li a { padding-left: 45px; }
|
||||
.tsd-navigation.secondary ul li li li a { padding-left: 65px; }
|
||||
.tsd-navigation.secondary ul li li li li a { padding-left: 85px; }
|
||||
.tsd-navigation.secondary ul li li li li li a { padding-left: 105px; }
|
||||
.tsd-navigation.secondary ul li li li li li li a { padding-left: 125px; }
|
||||
.tsd-navigation.secondary ul.current a { border-left-color: #eee; }
|
||||
.tsd-navigation.secondary li.focus > a, .tsd-navigation.secondary ul.current li.focus > a { border-left-color: #000; }
|
||||
.tsd-navigation.secondary li.current { margin-top: 20px; margin-bottom: 20px; border-left-color: #eee; }
|
||||
.tsd-navigation.secondary li.current > a { font-weight: bold; }
|
||||
|
||||
@media (min-width: 901px) { .menu-sticky-wrap { position: static; }
|
||||
.no-csspositionsticky .menu-sticky-wrap.sticky { position: fixed; }
|
||||
.no-csspositionsticky .menu-sticky-wrap.sticky-current { position: fixed; }
|
||||
.no-csspositionsticky .menu-sticky-wrap.sticky-current ul.before-current, .no-csspositionsticky .menu-sticky-wrap.sticky-current ul.after-current { opacity: 0; }
|
||||
.no-csspositionsticky .menu-sticky-wrap.sticky-bottom { position: absolute; top: auto !important; left: auto !important; bottom: 0; right: 0; }
|
||||
.csspositionsticky .menu-sticky-wrap.sticky { position: -webkit-sticky; position: sticky; }
|
||||
.csspositionsticky .menu-sticky-wrap.sticky-current { position: -webkit-sticky; position: sticky; } }
|
||||
|
||||
.tsd-panel { margin: 20px 0; padding: 20px; background-color: #fff; box-shadow: 0 0 4px rgba(0, 0, 0, 0.25); }
|
||||
.tsd-panel:empty { display: none; }
|
||||
.tsd-panel > h1, .tsd-panel > h2, .tsd-panel > h3 { margin: 1.5em -20px 10px -20px; padding: 0 20px 10px 20px; border-bottom: 1px solid #eee; }
|
||||
.tsd-panel > h1.tsd-before-signature, .tsd-panel > h2.tsd-before-signature, .tsd-panel > h3.tsd-before-signature { margin-bottom: 0; border-bottom: 0; }
|
||||
.tsd-panel table { display: block; width: 100%; overflow: auto; margin-top: 10px; word-break: normal; word-break: keep-all; }
|
||||
.tsd-panel table th { font-weight: bold; }
|
||||
.tsd-panel table th, .tsd-panel table td { padding: 6px 13px; border: 1px solid #ddd; }
|
||||
.tsd-panel table tr { background-color: #fff; border-top: 1px solid #ccc; }
|
||||
.tsd-panel table tr:nth-child(2n) { background-color: #f8f8f8; }
|
||||
|
||||
.tsd-panel-group { margin: 60px 0; }
|
||||
.tsd-panel-group > h1, .tsd-panel-group > h2, .tsd-panel-group > h3 { padding-left: 20px; padding-right: 20px; }
|
||||
|
||||
#tsd-search { transition: background-color 0.2s; }
|
||||
#tsd-search .title { position: relative; z-index: 2; }
|
||||
#tsd-search .field { position: absolute; left: 0; top: 0; right: 40px; height: 40px; }
|
||||
#tsd-search .field input { box-sizing: border-box; position: relative; top: -50px; z-index: 1; width: 100%; padding: 0 10px; opacity: 0; outline: 0; border: 0; background: transparent; color: #222; }
|
||||
#tsd-search .field label { position: absolute; overflow: hidden; right: -40px; }
|
||||
#tsd-search .field input, #tsd-search .title { transition: opacity 0.2s; }
|
||||
#tsd-search .results { position: absolute; visibility: hidden; top: 40px; width: 100%; margin: 0; padding: 0; list-style: none; box-shadow: 0 0 4px rgba(0, 0, 0, 0.25); }
|
||||
#tsd-search .results li { padding: 0 10px; background-color: #fdfdfd; }
|
||||
#tsd-search .results li:nth-child(even) { background-color: #fff; }
|
||||
#tsd-search .results li.state { display: none; }
|
||||
#tsd-search .results li.current, #tsd-search .results li:hover { background-color: #eee; }
|
||||
#tsd-search .results a { display: block; }
|
||||
#tsd-search .results a:before { top: 10px; }
|
||||
#tsd-search .results span.parent { color: #808080; font-weight: normal; }
|
||||
#tsd-search.has-focus { background-color: #eee; }
|
||||
#tsd-search.has-focus .field input { top: 0; opacity: 1; }
|
||||
#tsd-search.has-focus .title { z-index: 0; opacity: 0; }
|
||||
#tsd-search.has-focus .results { visibility: visible; }
|
||||
#tsd-search.loading .results li.state.loading { display: block; }
|
||||
#tsd-search.failure .results li.state.failure { display: block; }
|
||||
|
||||
.tsd-signature { margin: 0 0 1em 0; padding: 10px; border: 1px solid #eee; font-family: Menlo, Monaco, Consolas, "Courier New", monospace; font-size: 14px; }
|
||||
.tsd-signature.tsd-kind-icon { padding-left: 30px; }
|
||||
.tsd-signature.tsd-kind-icon:before { top: 10px; left: 10px; }
|
||||
.tsd-panel > .tsd-signature { margin-left: -20px; margin-right: -20px; border-width: 1px 0; }
|
||||
.tsd-panel > .tsd-signature.tsd-kind-icon { padding-left: 40px; }
|
||||
.tsd-panel > .tsd-signature.tsd-kind-icon:before { left: 20px; }
|
||||
|
||||
.tsd-signature-symbol { color: #808080; font-weight: normal; }
|
||||
|
||||
.tsd-signature-type { font-style: italic; font-weight: normal; }
|
||||
|
||||
.tsd-signatures { padding: 0; margin: 0 0 1em 0; border: 1px solid #eee; }
|
||||
.tsd-signatures .tsd-signature { margin: 0; border-width: 1px 0 0 0; transition: background-color 0.1s; }
|
||||
.tsd-signatures .tsd-signature:first-child { border-top-width: 0; }
|
||||
.tsd-signatures .tsd-signature.current { background-color: #eee; }
|
||||
.tsd-signatures.active > .tsd-signature { cursor: pointer; }
|
||||
.tsd-panel > .tsd-signatures { margin-left: -20px; margin-right: -20px; border-width: 1px 0; }
|
||||
.tsd-panel > .tsd-signatures .tsd-signature.tsd-kind-icon { padding-left: 40px; }
|
||||
.tsd-panel > .tsd-signatures .tsd-signature.tsd-kind-icon:before { left: 20px; }
|
||||
.tsd-panel > a.anchor + .tsd-signatures { border-top-width: 0; margin-top: -20px; }
|
||||
|
||||
ul.tsd-descriptions { position: relative; overflow: hidden; transition: height 0.3s; padding: 0; list-style: none; }
|
||||
ul.tsd-descriptions.active > .tsd-description { display: none; }
|
||||
ul.tsd-descriptions.active > .tsd-description.current { display: block; }
|
||||
ul.tsd-descriptions.active > .tsd-description.fade-in { -webkit-animation: fade-in-delayed 0.3s; animation: fade-in-delayed 0.3s; }
|
||||
ul.tsd-descriptions.active > .tsd-description.fade-out { -webkit-animation: fade-out-delayed 0.3s; animation: fade-out-delayed 0.3s; position: absolute; display: block; top: 0; left: 0; right: 0; opacity: 0; visibility: hidden; }
|
||||
ul.tsd-descriptions h4, ul.tsd-descriptions .tsd-index-panel h3, .tsd-index-panel ul.tsd-descriptions h3 { font-size: 16px; margin: 1em 0 0.5em 0; }
|
||||
|
||||
ul.tsd-parameters, ul.tsd-type-parameters { list-style: square; margin: 0; padding-left: 20px; }
|
||||
ul.tsd-parameters > li.tsd-parameter-siganture, ul.tsd-type-parameters > li.tsd-parameter-siganture { list-style: none; margin-left: -20px; }
|
||||
ul.tsd-parameters h5, ul.tsd-type-parameters h5 { font-size: 16px; margin: 1em 0 0.5em 0; }
|
||||
ul.tsd-parameters .tsd-comment, ul.tsd-type-parameters .tsd-comment { margin-top: -0.5em; }
|
||||
|
||||
.tsd-sources { font-size: 14px; color: #808080; margin: 0 0 1em 0; }
|
||||
.tsd-sources a { color: #808080; text-decoration: underline; }
|
||||
.tsd-sources ul, .tsd-sources p { margin: 0 !important; }
|
||||
.tsd-sources ul { list-style: none; padding: 0; }
|
||||
|
||||
.tsd-page-toolbar { position: absolute; z-index: 1; top: 0; left: 0; width: 100%; height: 40px; color: #333; background: #fff; border-bottom: 1px solid #eee; }
|
||||
.tsd-page-toolbar a { color: #333; text-decoration: none; }
|
||||
.tsd-page-toolbar a.title { font-weight: bold; }
|
||||
.tsd-page-toolbar a.title:hover { text-decoration: underline; }
|
||||
.tsd-page-toolbar .table-wrap { display: table; width: 100%; height: 40px; }
|
||||
.tsd-page-toolbar .table-cell { display: table-cell; position: relative; white-space: nowrap; line-height: 40px; }
|
||||
.tsd-page-toolbar .table-cell:first-child { width: 100%; }
|
||||
|
||||
.tsd-widget:before, .tsd-select .tsd-select-label:before, .tsd-select .tsd-select-list li:before { content: ""; display: inline-block; width: 40px; height: 40px; margin: 0 -8px 0 0; background-image: url(../images/widgets.png); background-repeat: no-repeat; text-indent: -1024px; vertical-align: bottom; }
|
||||
@media (-webkit-min-device-pixel-ratio: 1.5), (min-device-pixel-ratio: 1.5), (min-resolution: 144dpi) { .tsd-widget:before, .tsd-select .tsd-select-label:before, .tsd-select .tsd-select-list li:before { background-image: url(../images/widgets@2x.png); background-size: 320px 40px; } }
|
||||
|
||||
.tsd-widget { display: inline-block; overflow: hidden; opacity: 0.6; height: 40px; transition: opacity 0.1s, background-color 0.2s; vertical-align: bottom; cursor: pointer; }
|
||||
.tsd-widget:hover { opacity: 0.8; }
|
||||
.tsd-widget.active { opacity: 1; background-color: #eee; }
|
||||
.tsd-widget.no-caption { width: 40px; }
|
||||
.tsd-widget.no-caption:before { margin: 0; }
|
||||
.tsd-widget.search:before { background-position: 0 0; }
|
||||
.tsd-widget.menu:before { background-position: -40px 0; }
|
||||
.tsd-widget.options:before { background-position: -80px 0; }
|
||||
.tsd-widget.options, .tsd-widget.menu { display: none; }
|
||||
@media (max-width: 900px) { .tsd-widget.options, .tsd-widget.menu { display: inline-block; } }
|
||||
input[type=checkbox] + .tsd-widget:before { background-position: -120px 0; }
|
||||
input[type=checkbox]:checked + .tsd-widget:before { background-position: -160px 0; }
|
||||
|
||||
.tsd-select { position: relative; display: inline-block; height: 40px; transition: opacity 0.1s, background-color 0.2s; vertical-align: bottom; cursor: pointer; }
|
||||
.tsd-select .tsd-select-label { opacity: 0.6; transition: opacity 0.2s; }
|
||||
.tsd-select .tsd-select-label:before { background-position: -240px 0; }
|
||||
.tsd-select.active .tsd-select-label { opacity: 0.8; }
|
||||
.tsd-select.active .tsd-select-list { visibility: visible; opacity: 1; transition-delay: 0s; }
|
||||
.tsd-select .tsd-select-list { position: absolute; visibility: hidden; top: 40px; left: 0; margin: 0; padding: 0; opacity: 0; list-style: none; box-shadow: 0 0 4px rgba(0, 0, 0, 0.25); transition: visibility 0s 0.2s, opacity 0.2s; }
|
||||
.tsd-select .tsd-select-list li { padding: 0 20px 0 0; background-color: #fdfdfd; }
|
||||
.tsd-select .tsd-select-list li:before { background-position: 40px 0; }
|
||||
.tsd-select .tsd-select-list li:nth-child(even) { background-color: #fff; }
|
||||
.tsd-select .tsd-select-list li:hover { background-color: #eee; }
|
||||
.tsd-select .tsd-select-list li.selected:before { background-position: -200px 0; }
|
||||
@media (max-width: 900px) { .tsd-select .tsd-select-list { top: 0; left: auto; right: 100%; margin-right: -5px; }
|
||||
.tsd-select .tsd-select-label:before { background-position: -280px 0; } }
|
||||
|
||||
img { max-width: 100%; }
|
||||
File diff suppressed because one or more lines are too long
Binary file not shown.
|
Before Width: | Height: | Size: 9.3 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 27 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 480 B |
Binary file not shown.
|
Before Width: | Height: | Size: 855 B |
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
|
|
@ -1,206 +0,0 @@
|
|||
<!doctype html>
|
||||
<html class="default no-js">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||
<title>botlib</title>
|
||||
<meta name="description" content="">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<link rel="stylesheet" href="assets/css/main.css">
|
||||
</head>
|
||||
<body>
|
||||
<header>
|
||||
<div class="tsd-page-toolbar">
|
||||
<div class="container">
|
||||
<div class="table-wrap">
|
||||
<div class="table-cell" id="tsd-search" data-index="assets/js/search.js" data-base=".">
|
||||
<div class="field">
|
||||
<label for="tsd-search-field" class="tsd-widget search no-caption">Search</label>
|
||||
<input id="tsd-search-field" type="text" />
|
||||
</div>
|
||||
<ul class="results">
|
||||
<li class="state loading">Preparing search index...</li>
|
||||
<li class="state failure">The search index is not available</li>
|
||||
</ul>
|
||||
<a href="index.html" class="title">botlib</a>
|
||||
</div>
|
||||
<div class="table-cell" id="tsd-widgets">
|
||||
<div id="tsd-filter">
|
||||
<a href="#" class="tsd-widget options no-caption" data-toggle="options">Options</a>
|
||||
<div class="tsd-filter-group">
|
||||
<div class="tsd-select" id="tsd-filter-visibility">
|
||||
<span class="tsd-select-label">All</span>
|
||||
<ul class="tsd-select-list">
|
||||
<li data-value="public">Public</li>
|
||||
<li data-value="protected">Public/Protected</li>
|
||||
<li data-value="private" class="selected">All</li>
|
||||
</ul>
|
||||
</div>
|
||||
<input type="checkbox" id="tsd-filter-inherited" checked />
|
||||
<label class="tsd-widget" for="tsd-filter-inherited">Inherited</label>
|
||||
<input type="checkbox" id="tsd-filter-externals" checked />
|
||||
<label class="tsd-widget" for="tsd-filter-externals">Externals</label>
|
||||
<input type="checkbox" id="tsd-filter-only-exported" />
|
||||
<label class="tsd-widget" for="tsd-filter-only-exported">Only exported</label>
|
||||
</div>
|
||||
</div>
|
||||
<a href="#" class="tsd-widget menu no-caption" data-toggle="menu">Menu</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="tsd-page-title">
|
||||
<div class="container">
|
||||
<ul class="tsd-breadcrumb">
|
||||
<li>
|
||||
<a href="globals.html">Globals</a>
|
||||
</li>
|
||||
</ul>
|
||||
<h1> botlib</h1>
|
||||
</div>
|
||||
</div>
|
||||
</header>
|
||||
<div class="container container-main">
|
||||
<div class="row">
|
||||
<div class="col-8 col-content">
|
||||
<section class="tsd-panel-group tsd-index-group">
|
||||
<h2>Index</h2>
|
||||
<section class="tsd-panel tsd-index-panel">
|
||||
<div class="tsd-index-content">
|
||||
<section class="tsd-index-section ">
|
||||
<h3>External modules</h3>
|
||||
<ul class="tsd-index-list">
|
||||
<li class="tsd-kind-external-module"><a href="modules/_gberror_.html" class="tsd-kind-icon">"GBError"</a></li>
|
||||
<li class="tsd-kind-external-module"><a href="modules/_gbmininstance_.html" class="tsd-kind-icon">"GBMin<wbr>Instance"</a></li>
|
||||
<li class="tsd-kind-external-module"><a href="modules/_gbservice_.html" class="tsd-kind-icon">"GBService"</a></li>
|
||||
<li class="tsd-kind-external-module"><a href="modules/_igbadminservice_.html" class="tsd-kind-icon">"IGBAdmin<wbr>Service"</a></li>
|
||||
<li class="tsd-kind-external-module"><a href="modules/_igbconversationalservice_.html" class="tsd-kind-icon">"IGBConversational<wbr>Service"</a></li>
|
||||
<li class="tsd-kind-external-module"><a href="modules/_igbcoreservice_.html" class="tsd-kind-icon">"IGBCore<wbr>Service"</a></li>
|
||||
<li class="tsd-kind-external-module"><a href="modules/_igbdialog_.html" class="tsd-kind-icon">"IGBDialog"</a></li>
|
||||
<li class="tsd-kind-external-module"><a href="modules/_igbpackage_.html" class="tsd-kind-icon">"IGBPackage"</a></li>
|
||||
<li class="tsd-kind-external-module tsd-is-external"><a href="modules/_igbinstance_.html" class="tsd-kind-icon">"IGBinstance"</a></li>
|
||||
<li class="tsd-kind-external-module"><a href="modules/_index_.html" class="tsd-kind-icon">"index"</a></li>
|
||||
</ul>
|
||||
</section>
|
||||
</div>
|
||||
</section>
|
||||
</section>
|
||||
</div>
|
||||
<div class="col-4 col-menu menu-sticky-wrap menu-highlight">
|
||||
<nav class="tsd-navigation primary">
|
||||
<ul>
|
||||
<li class="globals current ">
|
||||
<a href="globals.html"><em>Globals</em></a>
|
||||
</li>
|
||||
<li class="label tsd-is-external">
|
||||
<span>Internals</span>
|
||||
</li>
|
||||
<li class=" tsd-kind-external-module">
|
||||
<a href="modules/_gberror_.html">"GBError"</a>
|
||||
</li>
|
||||
<li class=" tsd-kind-external-module">
|
||||
<a href="modules/_gbmininstance_.html">"GBMin<wbr>Instance"</a>
|
||||
</li>
|
||||
<li class=" tsd-kind-external-module">
|
||||
<a href="modules/_gbservice_.html">"GBService"</a>
|
||||
</li>
|
||||
<li class=" tsd-kind-external-module">
|
||||
<a href="modules/_igbadminservice_.html">"IGBAdmin<wbr>Service"</a>
|
||||
</li>
|
||||
<li class=" tsd-kind-external-module">
|
||||
<a href="modules/_igbconversationalservice_.html">"IGBConversational<wbr>Service"</a>
|
||||
</li>
|
||||
<li class=" tsd-kind-external-module">
|
||||
<a href="modules/_igbcoreservice_.html">"IGBCore<wbr>Service"</a>
|
||||
</li>
|
||||
<li class=" tsd-kind-external-module">
|
||||
<a href="modules/_igbdialog_.html">"IGBDialog"</a>
|
||||
</li>
|
||||
<li class=" tsd-kind-external-module">
|
||||
<a href="modules/_igbpackage_.html">"IGBPackage"</a>
|
||||
</li>
|
||||
<li class=" tsd-kind-external-module">
|
||||
<a href="modules/_index_.html">"index"</a>
|
||||
</li>
|
||||
<li class="label tsd-is-external">
|
||||
<span>Externals</span>
|
||||
</li>
|
||||
<li class=" tsd-kind-external-module tsd-is-external">
|
||||
<a href="modules/_igbinstance_.html">"IGBinstance"</a>
|
||||
</li>
|
||||
</ul>
|
||||
</nav>
|
||||
<nav class="tsd-navigation secondary menu-sticky">
|
||||
<ul class="before-current">
|
||||
</ul>
|
||||
</nav>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<footer class="with-border-bottom">
|
||||
<div class="container">
|
||||
<h2>Legend</h2>
|
||||
<div class="tsd-legend-group">
|
||||
<ul class="tsd-legend">
|
||||
<li class="tsd-kind-module"><span class="tsd-kind-icon">Module</span></li>
|
||||
<li class="tsd-kind-object-literal"><span class="tsd-kind-icon">Object literal</span></li>
|
||||
<li class="tsd-kind-variable"><span class="tsd-kind-icon">Variable</span></li>
|
||||
<li class="tsd-kind-function"><span class="tsd-kind-icon">Function</span></li>
|
||||
<li class="tsd-kind-function tsd-has-type-parameter"><span class="tsd-kind-icon">Function with type parameter</span></li>
|
||||
<li class="tsd-kind-index-signature"><span class="tsd-kind-icon">Index signature</span></li>
|
||||
<li class="tsd-kind-type-alias"><span class="tsd-kind-icon">Type alias</span></li>
|
||||
</ul>
|
||||
<ul class="tsd-legend">
|
||||
<li class="tsd-kind-enum"><span class="tsd-kind-icon">Enumeration</span></li>
|
||||
<li class="tsd-kind-enum-member"><span class="tsd-kind-icon">Enumeration member</span></li>
|
||||
<li class="tsd-kind-property tsd-parent-kind-enum"><span class="tsd-kind-icon">Property</span></li>
|
||||
<li class="tsd-kind-method tsd-parent-kind-enum"><span class="tsd-kind-icon">Method</span></li>
|
||||
</ul>
|
||||
<ul class="tsd-legend">
|
||||
<li class="tsd-kind-interface"><span class="tsd-kind-icon">Interface</span></li>
|
||||
<li class="tsd-kind-interface tsd-has-type-parameter"><span class="tsd-kind-icon">Interface with type parameter</span></li>
|
||||
<li class="tsd-kind-constructor tsd-parent-kind-interface"><span class="tsd-kind-icon">Constructor</span></li>
|
||||
<li class="tsd-kind-property tsd-parent-kind-interface"><span class="tsd-kind-icon">Property</span></li>
|
||||
<li class="tsd-kind-method tsd-parent-kind-interface"><span class="tsd-kind-icon">Method</span></li>
|
||||
<li class="tsd-kind-index-signature tsd-parent-kind-interface"><span class="tsd-kind-icon">Index signature</span></li>
|
||||
</ul>
|
||||
<ul class="tsd-legend">
|
||||
<li class="tsd-kind-class"><span class="tsd-kind-icon">Class</span></li>
|
||||
<li class="tsd-kind-class tsd-has-type-parameter"><span class="tsd-kind-icon">Class with type parameter</span></li>
|
||||
<li class="tsd-kind-constructor tsd-parent-kind-class"><span class="tsd-kind-icon">Constructor</span></li>
|
||||
<li class="tsd-kind-property tsd-parent-kind-class"><span class="tsd-kind-icon">Property</span></li>
|
||||
<li class="tsd-kind-method tsd-parent-kind-class"><span class="tsd-kind-icon">Method</span></li>
|
||||
<li class="tsd-kind-accessor tsd-parent-kind-class"><span class="tsd-kind-icon">Accessor</span></li>
|
||||
<li class="tsd-kind-index-signature tsd-parent-kind-class"><span class="tsd-kind-icon">Index signature</span></li>
|
||||
</ul>
|
||||
<ul class="tsd-legend">
|
||||
<li class="tsd-kind-constructor tsd-parent-kind-class tsd-is-inherited"><span class="tsd-kind-icon">Inherited constructor</span></li>
|
||||
<li class="tsd-kind-property tsd-parent-kind-class tsd-is-inherited"><span class="tsd-kind-icon">Inherited property</span></li>
|
||||
<li class="tsd-kind-method tsd-parent-kind-class tsd-is-inherited"><span class="tsd-kind-icon">Inherited method</span></li>
|
||||
<li class="tsd-kind-accessor tsd-parent-kind-class tsd-is-inherited"><span class="tsd-kind-icon">Inherited accessor</span></li>
|
||||
</ul>
|
||||
<ul class="tsd-legend">
|
||||
<li class="tsd-kind-property tsd-parent-kind-class tsd-is-protected"><span class="tsd-kind-icon">Protected property</span></li>
|
||||
<li class="tsd-kind-method tsd-parent-kind-class tsd-is-protected"><span class="tsd-kind-icon">Protected method</span></li>
|
||||
<li class="tsd-kind-accessor tsd-parent-kind-class tsd-is-protected"><span class="tsd-kind-icon">Protected accessor</span></li>
|
||||
</ul>
|
||||
<ul class="tsd-legend">
|
||||
<li class="tsd-kind-property tsd-parent-kind-class tsd-is-private"><span class="tsd-kind-icon">Private property</span></li>
|
||||
<li class="tsd-kind-method tsd-parent-kind-class tsd-is-private"><span class="tsd-kind-icon">Private method</span></li>
|
||||
<li class="tsd-kind-accessor tsd-parent-kind-class tsd-is-private"><span class="tsd-kind-icon">Private accessor</span></li>
|
||||
</ul>
|
||||
<ul class="tsd-legend">
|
||||
<li class="tsd-kind-property tsd-parent-kind-class tsd-is-static"><span class="tsd-kind-icon">Static property</span></li>
|
||||
<li class="tsd-kind-call-signature tsd-parent-kind-class tsd-is-static"><span class="tsd-kind-icon">Static method</span></li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</footer>
|
||||
<div class="container tsd-generator">
|
||||
<p>Generated using <a href="http://typedoc.org/" target="_blank">TypeDoc</a></p>
|
||||
</div>
|
||||
<div class="overlay"></div>
|
||||
<script src="assets/js/main.js"></script>
|
||||
<script>if (location.protocol == 'file:') document.write('<script src="assets/js/search.js"><' + '/script>');</script>
|
||||
</body>
|
||||
</html>
|
||||
188
docs/index.html
188
docs/index.html
|
|
@ -1,188 +0,0 @@
|
|||
<!doctype html>
|
||||
<html class="default no-js">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||
<title>botlib</title>
|
||||
<meta name="description" content="">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<link rel="stylesheet" href="assets/css/main.css">
|
||||
</head>
|
||||
<body>
|
||||
<header>
|
||||
<div class="tsd-page-toolbar">
|
||||
<div class="container">
|
||||
<div class="table-wrap">
|
||||
<div class="table-cell" id="tsd-search" data-index="assets/js/search.js" data-base=".">
|
||||
<div class="field">
|
||||
<label for="tsd-search-field" class="tsd-widget search no-caption">Search</label>
|
||||
<input id="tsd-search-field" type="text" />
|
||||
</div>
|
||||
<ul class="results">
|
||||
<li class="state loading">Preparing search index...</li>
|
||||
<li class="state failure">The search index is not available</li>
|
||||
</ul>
|
||||
<a href="index.html" class="title">botlib</a>
|
||||
</div>
|
||||
<div class="table-cell" id="tsd-widgets">
|
||||
<div id="tsd-filter">
|
||||
<a href="#" class="tsd-widget options no-caption" data-toggle="options">Options</a>
|
||||
<div class="tsd-filter-group">
|
||||
<div class="tsd-select" id="tsd-filter-visibility">
|
||||
<span class="tsd-select-label">All</span>
|
||||
<ul class="tsd-select-list">
|
||||
<li data-value="public">Public</li>
|
||||
<li data-value="protected">Public/Protected</li>
|
||||
<li data-value="private" class="selected">All</li>
|
||||
</ul>
|
||||
</div>
|
||||
<input type="checkbox" id="tsd-filter-inherited" checked />
|
||||
<label class="tsd-widget" for="tsd-filter-inherited">Inherited</label>
|
||||
<input type="checkbox" id="tsd-filter-externals" checked />
|
||||
<label class="tsd-widget" for="tsd-filter-externals">Externals</label>
|
||||
<input type="checkbox" id="tsd-filter-only-exported" />
|
||||
<label class="tsd-widget" for="tsd-filter-only-exported">Only exported</label>
|
||||
</div>
|
||||
</div>
|
||||
<a href="#" class="tsd-widget menu no-caption" data-toggle="menu">Menu</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="tsd-page-title">
|
||||
<div class="container">
|
||||
<ul class="tsd-breadcrumb">
|
||||
<li>
|
||||
<a href="globals.html">Globals</a>
|
||||
</li>
|
||||
</ul>
|
||||
<h1> botlib</h1>
|
||||
</div>
|
||||
</div>
|
||||
</header>
|
||||
<div class="container container-main">
|
||||
<div class="row">
|
||||
<div class="col-8 col-content">
|
||||
<div class="tsd-panel tsd-typography">
|
||||
<p>General Bots base library for building Node.js TypeScript Apps packages (.gbapp).</p>
|
||||
<p>See: <a href="https://github.com/pragmatismo-io/BotServer">https://github.com/pragmatismo-io/BotServer</a> for main documentation.</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-4 col-menu menu-sticky-wrap menu-highlight">
|
||||
<nav class="tsd-navigation primary">
|
||||
<ul>
|
||||
<li class="globals ">
|
||||
<a href="globals.html"><em>Globals</em></a>
|
||||
</li>
|
||||
<li class="label tsd-is-external">
|
||||
<span>Internals</span>
|
||||
</li>
|
||||
<li class=" tsd-kind-external-module">
|
||||
<a href="modules/_gberror_.html">"GBError"</a>
|
||||
</li>
|
||||
<li class=" tsd-kind-external-module">
|
||||
<a href="modules/_gbmininstance_.html">"GBMin<wbr>Instance"</a>
|
||||
</li>
|
||||
<li class=" tsd-kind-external-module">
|
||||
<a href="modules/_gbservice_.html">"GBService"</a>
|
||||
</li>
|
||||
<li class=" tsd-kind-external-module">
|
||||
<a href="modules/_igbadminservice_.html">"IGBAdmin<wbr>Service"</a>
|
||||
</li>
|
||||
<li class=" tsd-kind-external-module">
|
||||
<a href="modules/_igbconversationalservice_.html">"IGBConversational<wbr>Service"</a>
|
||||
</li>
|
||||
<li class=" tsd-kind-external-module">
|
||||
<a href="modules/_igbcoreservice_.html">"IGBCore<wbr>Service"</a>
|
||||
</li>
|
||||
<li class=" tsd-kind-external-module">
|
||||
<a href="modules/_igbdialog_.html">"IGBDialog"</a>
|
||||
</li>
|
||||
<li class=" tsd-kind-external-module">
|
||||
<a href="modules/_igbpackage_.html">"IGBPackage"</a>
|
||||
</li>
|
||||
<li class=" tsd-kind-external-module">
|
||||
<a href="modules/_index_.html">"index"</a>
|
||||
</li>
|
||||
<li class="label tsd-is-external">
|
||||
<span>Externals</span>
|
||||
</li>
|
||||
<li class=" tsd-kind-external-module tsd-is-external">
|
||||
<a href="modules/_igbinstance_.html">"IGBinstance"</a>
|
||||
</li>
|
||||
</ul>
|
||||
</nav>
|
||||
<nav class="tsd-navigation secondary menu-sticky">
|
||||
<ul class="before-current">
|
||||
</ul>
|
||||
</nav>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<footer class="with-border-bottom">
|
||||
<div class="container">
|
||||
<h2>Legend</h2>
|
||||
<div class="tsd-legend-group">
|
||||
<ul class="tsd-legend">
|
||||
<li class="tsd-kind-module"><span class="tsd-kind-icon">Module</span></li>
|
||||
<li class="tsd-kind-object-literal"><span class="tsd-kind-icon">Object literal</span></li>
|
||||
<li class="tsd-kind-variable"><span class="tsd-kind-icon">Variable</span></li>
|
||||
<li class="tsd-kind-function"><span class="tsd-kind-icon">Function</span></li>
|
||||
<li class="tsd-kind-function tsd-has-type-parameter"><span class="tsd-kind-icon">Function with type parameter</span></li>
|
||||
<li class="tsd-kind-index-signature"><span class="tsd-kind-icon">Index signature</span></li>
|
||||
<li class="tsd-kind-type-alias"><span class="tsd-kind-icon">Type alias</span></li>
|
||||
</ul>
|
||||
<ul class="tsd-legend">
|
||||
<li class="tsd-kind-enum"><span class="tsd-kind-icon">Enumeration</span></li>
|
||||
<li class="tsd-kind-enum-member"><span class="tsd-kind-icon">Enumeration member</span></li>
|
||||
<li class="tsd-kind-property tsd-parent-kind-enum"><span class="tsd-kind-icon">Property</span></li>
|
||||
<li class="tsd-kind-method tsd-parent-kind-enum"><span class="tsd-kind-icon">Method</span></li>
|
||||
</ul>
|
||||
<ul class="tsd-legend">
|
||||
<li class="tsd-kind-interface"><span class="tsd-kind-icon">Interface</span></li>
|
||||
<li class="tsd-kind-interface tsd-has-type-parameter"><span class="tsd-kind-icon">Interface with type parameter</span></li>
|
||||
<li class="tsd-kind-constructor tsd-parent-kind-interface"><span class="tsd-kind-icon">Constructor</span></li>
|
||||
<li class="tsd-kind-property tsd-parent-kind-interface"><span class="tsd-kind-icon">Property</span></li>
|
||||
<li class="tsd-kind-method tsd-parent-kind-interface"><span class="tsd-kind-icon">Method</span></li>
|
||||
<li class="tsd-kind-index-signature tsd-parent-kind-interface"><span class="tsd-kind-icon">Index signature</span></li>
|
||||
</ul>
|
||||
<ul class="tsd-legend">
|
||||
<li class="tsd-kind-class"><span class="tsd-kind-icon">Class</span></li>
|
||||
<li class="tsd-kind-class tsd-has-type-parameter"><span class="tsd-kind-icon">Class with type parameter</span></li>
|
||||
<li class="tsd-kind-constructor tsd-parent-kind-class"><span class="tsd-kind-icon">Constructor</span></li>
|
||||
<li class="tsd-kind-property tsd-parent-kind-class"><span class="tsd-kind-icon">Property</span></li>
|
||||
<li class="tsd-kind-method tsd-parent-kind-class"><span class="tsd-kind-icon">Method</span></li>
|
||||
<li class="tsd-kind-accessor tsd-parent-kind-class"><span class="tsd-kind-icon">Accessor</span></li>
|
||||
<li class="tsd-kind-index-signature tsd-parent-kind-class"><span class="tsd-kind-icon">Index signature</span></li>
|
||||
</ul>
|
||||
<ul class="tsd-legend">
|
||||
<li class="tsd-kind-constructor tsd-parent-kind-class tsd-is-inherited"><span class="tsd-kind-icon">Inherited constructor</span></li>
|
||||
<li class="tsd-kind-property tsd-parent-kind-class tsd-is-inherited"><span class="tsd-kind-icon">Inherited property</span></li>
|
||||
<li class="tsd-kind-method tsd-parent-kind-class tsd-is-inherited"><span class="tsd-kind-icon">Inherited method</span></li>
|
||||
<li class="tsd-kind-accessor tsd-parent-kind-class tsd-is-inherited"><span class="tsd-kind-icon">Inherited accessor</span></li>
|
||||
</ul>
|
||||
<ul class="tsd-legend">
|
||||
<li class="tsd-kind-property tsd-parent-kind-class tsd-is-protected"><span class="tsd-kind-icon">Protected property</span></li>
|
||||
<li class="tsd-kind-method tsd-parent-kind-class tsd-is-protected"><span class="tsd-kind-icon">Protected method</span></li>
|
||||
<li class="tsd-kind-accessor tsd-parent-kind-class tsd-is-protected"><span class="tsd-kind-icon">Protected accessor</span></li>
|
||||
</ul>
|
||||
<ul class="tsd-legend">
|
||||
<li class="tsd-kind-property tsd-parent-kind-class tsd-is-private"><span class="tsd-kind-icon">Private property</span></li>
|
||||
<li class="tsd-kind-method tsd-parent-kind-class tsd-is-private"><span class="tsd-kind-icon">Private method</span></li>
|
||||
<li class="tsd-kind-accessor tsd-parent-kind-class tsd-is-private"><span class="tsd-kind-icon">Private accessor</span></li>
|
||||
</ul>
|
||||
<ul class="tsd-legend">
|
||||
<li class="tsd-kind-property tsd-parent-kind-class tsd-is-static"><span class="tsd-kind-icon">Static property</span></li>
|
||||
<li class="tsd-kind-call-signature tsd-parent-kind-class tsd-is-static"><span class="tsd-kind-icon">Static method</span></li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</footer>
|
||||
<div class="container tsd-generator">
|
||||
<p>Generated using <a href="http://typedoc.org/" target="_blank">TypeDoc</a></p>
|
||||
</div>
|
||||
<div class="overlay"></div>
|
||||
<script src="assets/js/main.js"></script>
|
||||
<script>if (location.protocol == 'file:') document.write('<script src="assets/js/search.js"><' + '/script>');</script>
|
||||
</body>
|
||||
</html>
|
||||
10229
package-lock.json
generated
10229
package-lock.json
generated
File diff suppressed because it is too large
Load diff
52
package.json
52
package.json
|
|
@ -1,52 +0,0 @@
|
|||
{
|
||||
"name": "botlib",
|
||||
"version": "5.0.0",
|
||||
"description": "General Bot base library for building Node.js TypeScript Apps packages (.gbapp) and Libray packages (.gblib)",
|
||||
"main": "dist/index.js",
|
||||
"types": "dist/index",
|
||||
"homepage": "http://www.generalbots.ai",
|
||||
"contributors": [
|
||||
"Rodrigo Rodriguez <me@rodrigorodriguez.com>",
|
||||
"João Antonio Ferreira <joao.parana@gmail.com>",
|
||||
"Jorge Ramos <jramos@pobox.com>",
|
||||
"PH <ph.an@outlook.com>",
|
||||
"Dário Vieira <dario.junior3@gmail.com>"
|
||||
],
|
||||
"license": "AGPL-3.0",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/GeneralBots/BotLib.git"
|
||||
},
|
||||
"scripts": {
|
||||
"clean": "rm -rf node_modules/ dist/",
|
||||
"build": "npm install && npm run build-lib",
|
||||
"build-lib": "tsc"
|
||||
},
|
||||
"dependencies": {
|
||||
"async": "3.2.6",
|
||||
"botbuilder": "4.23.0",
|
||||
"botbuilder-adapter-facebook": "1.0.12",
|
||||
"botbuilder-ai": "4.23.0",
|
||||
"botbuilder-azure": "4.23.0",
|
||||
"botbuilder-dialogs": "4.23.0",
|
||||
"botframework-connector": "4.23.0",
|
||||
"chrono-node": "2.7.5",
|
||||
"dotenv-extended": "2.9.0",
|
||||
"iconv-lite": "0.6.3",
|
||||
"ms": "2.1.3",
|
||||
"pragmatismo-io-framework": "1.1.1",
|
||||
"reflect-metadata": "0.2.2",
|
||||
"sequelize": "6.37.3",
|
||||
"sequelize-cli": "6.6.2",
|
||||
"sequelize-typescript": "2.1.6",
|
||||
"underscore": "1.13.7",
|
||||
"winston": "3.14.2"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/sequelize": "4.28.20",
|
||||
"@types/winston": "2.4.4",
|
||||
"ts-node": "10.9.2",
|
||||
"typedoc": "0.26.6",
|
||||
"typescript": "5.5.4"
|
||||
}
|
||||
}
|
||||
|
|
@ -1,5 +0,0 @@
|
|||
import { DialogContext } from "botbuilder-dialogs";
|
||||
|
||||
|
||||
export class GBDialogStep extends DialogContext {
|
||||
}
|
||||
|
|
@ -1,56 +0,0 @@
|
|||
/*****************************************************************************\
|
||||
| █████ █████ ██ █ █████ █████ ████ ██ ████ █████ █████ ███ ® |
|
||||
| ██ █ ███ █ █ ██ ██ ██ ██ ██ ██ █ ██ ██ █ █ |
|
||||
| ██ ███ ████ █ ██ █ ████ █████ ██████ ██ ████ █ █ █ ██ |
|
||||
| ██ ██ █ █ ██ █ █ ██ ██ ██ ██ ██ ██ █ ██ ██ █ █ |
|
||||
| █████ █████ █ ███ █████ ██ ██ ██ ██ █████ ████ █████ █ ███ |
|
||||
| |
|
||||
| General Bots Copyright (c) pragmatismo.cloud. All rights reserved. |
|
||||
| Licensed under the AGPL-3.0. |
|
||||
| |
|
||||
| According to our dual licensing model, this program can be used either |
|
||||
| under the terms of the GNU Affero General Public License, version 3, |
|
||||
| or under a proprietary license. |
|
||||
| |
|
||||
| The texts of the GNU Affero General Public License with an additional |
|
||||
| permission and of our proprietary license can be found at and |
|
||||
| in the LICENSE file you have received along with this program. |
|
||||
| |
|
||||
| This program is distributed in the hope that it will be useful, |
|
||||
| but WITHOUT ANY WARRANTY, without even the implied warranty of |
|
||||
| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|
||||
| GNU Affero General Public License for more details. |
|
||||
| |
|
||||
| "General Bots" is a registered trademark of pragmatismo.cloud. |
|
||||
| The licensing of the program under the AGPLv3 does not imply a |
|
||||
| trademark license. Therefore any rights, title and interest in |
|
||||
| our trademarks remain entirely with us. |
|
||||
| |
|
||||
\*****************************************************************************/
|
||||
|
||||
'use strict'
|
||||
|
||||
export enum GBERROR_TYPE {
|
||||
generalError = 2,
|
||||
nlpGeneralError = 3,
|
||||
}
|
||||
|
||||
export class GBError {
|
||||
static createFromCode(GBERROR_TYPE): any { }
|
||||
|
||||
getMessageFromErrorCode(type: GBERROR_TYPE) {
|
||||
if (type === GBERROR_TYPE.nlpGeneralError) {
|
||||
return `Error accessing NLP, check of the service.`
|
||||
}
|
||||
}
|
||||
|
||||
e: Error
|
||||
|
||||
constructor(e: Error, type: GBERROR_TYPE = GBERROR_TYPE.generalError) {
|
||||
this.e = e
|
||||
}
|
||||
|
||||
static create(message) {
|
||||
return new GBError(Error(message))
|
||||
}
|
||||
}
|
||||
30
src/GBLog.ts
30
src/GBLog.ts
|
|
@ -1,30 +0,0 @@
|
|||
|
||||
const loggers = require("./logger");
|
||||
|
||||
export class GBLog {
|
||||
public static getLogger() { return loggers; }
|
||||
public static error(params): void {
|
||||
loggers[0].error(params);
|
||||
loggers[1].error(params);
|
||||
}
|
||||
public static warn(params): void {
|
||||
loggers[0].warn(params);
|
||||
loggers[1].warn(params);
|
||||
}
|
||||
public static info(params): void {
|
||||
loggers[0].info(params);
|
||||
loggers[1].info(params);
|
||||
}
|
||||
public static debug(params): void {
|
||||
loggers[0].debug(params);
|
||||
loggers[1].debug(params);
|
||||
}
|
||||
public static verbose(params): void {
|
||||
loggers[0].verbose(params);
|
||||
loggers[1].verbose(params);
|
||||
}
|
||||
public static silly(params): void {
|
||||
loggers[0].silly(params);
|
||||
loggers[1].silly(params);
|
||||
}
|
||||
}
|
||||
|
|
@ -1,70 +0,0 @@
|
|||
/*****************************************************************************\
|
||||
| █████ █████ ██ █ █████ █████ ████ ██ ████ █████ █████ ███ ® |
|
||||
| ██ █ ███ █ █ ██ ██ ██ ██ ██ ██ █ ██ ██ █ █ |
|
||||
| ██ ███ ████ █ ██ █ ████ █████ ██████ ██ ████ █ █ █ ██ |
|
||||
| ██ ██ █ █ ██ █ █ ██ ██ ██ ██ ██ ██ █ ██ ██ █ █ |
|
||||
| █████ █████ █ ███ █████ ██ ██ ██ ██ █████ ████ █████ █ ███ |
|
||||
| |
|
||||
| General Bots Copyright (c) pragmatismo.cloud. All rights reserved. |
|
||||
| Licensed under the AGPL-3.0. |
|
||||
| |
|
||||
| According to our dual licensing model, this program can be used either |
|
||||
| under the terms of the GNU Affero General Public License, version 3, |
|
||||
| or under a proprietary license. |
|
||||
| |
|
||||
| The texts of the GNU Affero General Public License with an additional |
|
||||
| permission and of our proprietary license can be found at and |
|
||||
| in the LICENSE file you have received along with this program. |
|
||||
| |
|
||||
| This program is distributed in the hope that it will be useful, |
|
||||
| but WITHOUT ANY WARRANTY, without even the implied warranty of |
|
||||
| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|
||||
| GNU Affero General Public License for more details. |
|
||||
| |
|
||||
| "General Bots" is a registered trademark of pragmatismo.cloud. |
|
||||
| The licensing of the program under the AGPLv3 does not imply a |
|
||||
| trademark license. Therefore any rights, title and interest in |
|
||||
| our trademarks remain entirely with us. |
|
||||
| |
|
||||
\*****************************************************************************/
|
||||
|
||||
import { BotAdapter, UserState } from "botbuilder";
|
||||
import { DialogSet } from "botbuilder-dialogs";
|
||||
import { IGBInstance } from ".";
|
||||
import { IGBCoreService } from "./IGBCoreService";
|
||||
import { IGBConversationalService, IGBPackage } from ".";
|
||||
import { AzureText } from "pragmatismo-io-framework";
|
||||
import { IGBAdminService } from "./IGBAdminService";
|
||||
import { IGBDeployer } from "./IGBDeployer";
|
||||
import { IGBKBService } from "./IGBKBService";
|
||||
|
||||
/** Minimal services for bot. */
|
||||
|
||||
export class GBMinInstance {
|
||||
packages: IGBPackage[];
|
||||
appPackages: IGBPackage[];
|
||||
botId: string;
|
||||
instance: IGBInstance;
|
||||
core: IGBCoreService;
|
||||
conversationalService: IGBConversationalService;
|
||||
kbService: IGBKBService;
|
||||
adminService: IGBAdminService;
|
||||
deployService: IGBDeployer;
|
||||
textServices: AzureText;
|
||||
bot: BotAdapter;
|
||||
dialogs: DialogSet;
|
||||
userState: UserState;
|
||||
userProfile: any;
|
||||
whatsAppDirectLine: any;
|
||||
|
||||
|
||||
cbMap: {};
|
||||
scriptMap: {};
|
||||
sandBoxMap: {};
|
||||
gbappServices: Array<any> = [];
|
||||
|
||||
constructor() {
|
||||
this.packages = [];
|
||||
this.gbappServices = [];
|
||||
}
|
||||
}
|
||||
|
|
@ -1,33 +0,0 @@
|
|||
/*****************************************************************************\
|
||||
| █████ █████ ██ █ █████ █████ ████ ██ ████ █████ █████ ███ ® |
|
||||
| ██ █ ███ █ █ ██ ██ ██ ██ ██ ██ █ ██ ██ █ █ |
|
||||
| ██ ███ ████ █ ██ █ ████ █████ ██████ ██ ████ █ █ █ ██ |
|
||||
| ██ ██ █ █ ██ █ █ ██ ██ ██ ██ ██ ██ █ ██ ██ █ █ |
|
||||
| █████ █████ █ ███ █████ ██ ██ ██ ██ █████ ████ █████ █ ███ |
|
||||
| |
|
||||
| General Bots Copyright (c) pragmatismo.cloud. All rights reserved. |
|
||||
| Licensed under the AGPL-3.0. |
|
||||
| |
|
||||
| According to our dual licensing model, this program can be used either |
|
||||
| under the terms of the GNU Affero General Public License, version 3, |
|
||||
| or under a proprietary license. |
|
||||
| |
|
||||
| The texts of the GNU Affero General Public License with an additional |
|
||||
| permission and of our proprietary license can be found at and |
|
||||
| in the LICENSE file you have received along with this program. |
|
||||
| |
|
||||
| This program is distributed in the hope that it will be useful, |
|
||||
| but WITHOUT ANY WARRANTY, without even the implied warranty of |
|
||||
| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|
||||
| GNU Affero General Public License for more details. |
|
||||
| |
|
||||
| "General Bots" is a registered trademark of pragmatismo.cloud. |
|
||||
| The licensing of the program under the AGPLv3 does not imply a |
|
||||
| trademark license. Therefore any rights, title and interest in |
|
||||
| our trademarks remain entirely with us. |
|
||||
| |
|
||||
\*****************************************************************************/
|
||||
|
||||
'use strict'
|
||||
|
||||
export class GBService { }
|
||||
|
|
@ -1,47 +0,0 @@
|
|||
/*****************************************************************************\
|
||||
| █████ █████ ██ █ █████ █████ ████ ██ ████ █████ █████ ███ ® |
|
||||
| ██ █ ███ █ █ ██ ██ ██ ██ ██ ██ █ ██ ██ █ █ |
|
||||
| ██ ███ ████ █ ██ █ ████ █████ ██████ ██ ████ █ █ █ ██ |
|
||||
| ██ ██ █ █ ██ █ █ ██ ██ ██ ██ ██ ██ █ ██ ██ █ █ |
|
||||
| █████ █████ █ ███ █████ ██ ██ ██ ██ █████ ████ █████ █ ███ |
|
||||
| |
|
||||
| General Bots Copyright (c) pragmatismo.cloud. All rights reserved. |
|
||||
| Licensed under the AGPL-3.0. |
|
||||
| |
|
||||
| According to our dual licensing model, this program can be used either |
|
||||
| under the terms of the GNU Affero General Public License, version 3, |
|
||||
| or under a proprietary license. |
|
||||
| |
|
||||
| The texts of the GNU Affero General Public License with an additional |
|
||||
| permission and of our proprietary license can be found at and |
|
||||
| in the LICENSE file you have received along with this program. |
|
||||
| |
|
||||
| This program is distributed in the hope that it will be useful, |
|
||||
| but WITHOUT ANY WARRANTY, without even the implied warranty of |
|
||||
| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|
||||
| GNU Affero General Public License for more details. |
|
||||
| |
|
||||
| "General Bots" is a registered trademark of pragmatismo.cloud. |
|
||||
| The licensing of the program under the AGPLv3 does not imply a |
|
||||
| trademark license. Therefore any rights, title and interest in |
|
||||
| our trademarks remain entirely with us. |
|
||||
| |
|
||||
\*****************************************************************************/
|
||||
|
||||
"use strict";
|
||||
|
||||
import { IGBInstance } from ".";
|
||||
import { GBMinInstance } from "./GBMinInstance";
|
||||
|
||||
export interface IGBAdminService {
|
||||
acquireElevatedToken(instanceId): Promise<string>;
|
||||
updateSecurityInfo(
|
||||
instanceId: number,
|
||||
authenticatorTenant: string,
|
||||
authenticatorAuthorityHostUrl: string
|
||||
): Promise<IGBInstance>;
|
||||
|
||||
getValue(instanceId: number, key: string): Promise<string>;
|
||||
setValue(instanceId: number, key: string, value: string): Promise<void>;
|
||||
publish(min: GBMinInstance, packageName: string, republish: boolean): Promise<void>;
|
||||
}
|
||||
|
|
@ -1,51 +0,0 @@
|
|||
/*****************************************************************************\
|
||||
| █████ █████ ██ █ █████ █████ ████ ██ ████ █████ █████ ███ ® |
|
||||
| ██ █ ███ █ █ ██ ██ ██ ██ ██ ██ █ ██ ██ █ █ |
|
||||
| ██ ███ ████ █ ██ █ ████ █████ ██████ ██ ████ █ █ █ ██ |
|
||||
| ██ ██ █ █ ██ █ █ ██ ██ ██ ██ ██ ██ █ ██ ██ █ █ |
|
||||
| █████ █████ █ ███ █████ ██ ██ ██ ██ █████ ████ █████ █ ███ |
|
||||
| |
|
||||
| General Bots Copyright (c) pragmatismo.cloud. All rights reserved. |
|
||||
| Licensed under the AGPL-3.0. |
|
||||
| |
|
||||
| According to our dual licensing model, this program can be used either |
|
||||
| under the terms of the GNU Affero General Public License, version 3, |
|
||||
| or under a proprietary license. |
|
||||
| |
|
||||
| The texts of the GNU Affero General Public License with an additional |
|
||||
| permission and of our proprietary license can be found at and |
|
||||
| in the LICENSE file you have received along with this program. |
|
||||
| |
|
||||
| This program is distributed in the hope that it will be useful, |
|
||||
| but WITHOUT ANY WARRANTY, without even the implied warranty of |
|
||||
| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|
||||
| GNU Affero General Public License for more details. |
|
||||
| |
|
||||
| "General Bots" is a registered trademark of pragmatismo.cloud. |
|
||||
| The licensing of the program under the AGPLv3 does not imply a |
|
||||
| trademark license. Therefore any rights, title and interest in |
|
||||
| our trademarks remain entirely with us. |
|
||||
| |
|
||||
\*****************************************************************************/
|
||||
|
||||
'use strict';
|
||||
|
||||
import { GBMinInstance } from './GBMinInstance';
|
||||
import { GBDialogStep } from './GBDialogStep';
|
||||
|
||||
export interface IGBConversationalService {
|
||||
prompt(min: GBMinInstance, step: GBDialogStep, text: string);
|
||||
sendText(min: GBMinInstance, step: GBDialogStep, text: string);
|
||||
sendEvent(min: GBMinInstance, step: GBDialogStep, name: string, value: Object);
|
||||
sendFile(min: GBMinInstance, step: GBDialogStep, mobile: string, url: string, caption: string);
|
||||
sendAudio(min: GBMinInstance, step: GBDialogStep, url: string);
|
||||
prompt(min: GBMinInstance, step: GBDialogStep, text: string);
|
||||
sendSms(min: GBMinInstance, mobile: string, text: string);
|
||||
routeNLP(step: GBDialogStep, min: GBMinInstance, text: string);
|
||||
getCurrentLanguage(step: GBDialogStep);
|
||||
getNewMobileCode();
|
||||
sendMarkdownToMobile(min: GBMinInstance, step: GBDialogStep, mobile: string, text: string);
|
||||
translate(min: GBMinInstance, text: string, language: string): Promise<string>;
|
||||
getLanguage(min: GBMinInstance, text: string): Promise<string>;
|
||||
spellCheck(min: GBMinInstance, text: string): Promise<string>;
|
||||
}
|
||||
|
|
@ -1,64 +0,0 @@
|
|||
/*****************************************************************************\
|
||||
| █████ █████ ██ █ █████ █████ ████ ██ ████ █████ █████ ███ ® |
|
||||
| ██ █ ███ █ █ ██ ██ ██ ██ ██ ██ █ ██ ██ █ █ |
|
||||
| ██ ███ ████ █ ██ █ ████ █████ ██████ ██ ████ █ █ █ ██ |
|
||||
| ██ ██ █ █ ██ █ █ ██ ██ ██ ██ ██ ██ █ ██ ██ █ █ |
|
||||
| █████ █████ █ ███ █████ ██ ██ ██ ██ █████ ████ █████ █ ███ |
|
||||
| |
|
||||
| General Bots Copyright (c) pragmatismo.cloud. All rights reserved. |
|
||||
| Licensed under the AGPL-3.0. |
|
||||
| |
|
||||
| According to our dual licensing model, this program can be used either |
|
||||
| under the terms of the GNU Affero General Public License, version 3, |
|
||||
| or under a proprietary license. |
|
||||
| |
|
||||
| The texts of the GNU Affero General Public License with an additional |
|
||||
| permission and of our proprietary license can be found at and |
|
||||
| in the LICENSE file you have received along with this program. |
|
||||
| |
|
||||
| This program is distributed in the hope that it will be useful, |
|
||||
| but WITHOUT ANY WARRANTY, without even the implied warranty of |
|
||||
| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|
||||
| GNU Affero General Public License for more details. |
|
||||
| |
|
||||
| "General Bots" is a registered trademark of pragmatismo.cloud. |
|
||||
| The licensing of the program under the AGPLv3 does not imply a |
|
||||
| trademark license. Therefore any rights, title and interest in |
|
||||
| our trademarks remain entirely with us. |
|
||||
| |
|
||||
\*****************************************************************************/
|
||||
|
||||
"use strict"
|
||||
|
||||
import { Sequelize } from "sequelize-typescript"
|
||||
import { IGBInstance } from "./IGBInstance"
|
||||
import { IGBInstallationDeployer } from "./IGBInstallationDeployer";
|
||||
import { IGBPackage } from "./IGBPackage";
|
||||
|
||||
/**
|
||||
* This interface defines the core service which is shared among
|
||||
* bot packages so they can have direct access to base services.
|
||||
*/
|
||||
export interface IGBCoreService {
|
||||
sequelize: Sequelize
|
||||
syncDatabaseStructure()
|
||||
loadInstances(): Promise<IGBInstance[]>;
|
||||
deleteInstance(botId: string): Promise<void>;
|
||||
loadInstanceByBotId(botId: string): Promise<IGBInstance>;
|
||||
loadInstanceByActivationCode(activationCode: string): Promise<IGBInstance>;
|
||||
loadInstanceById(instanceId: number): Promise<IGBInstance>;
|
||||
initStorage(): Promise<any>;
|
||||
createBootInstance(core: IGBCoreService, installationDeployer: IGBInstallationDeployer, proxyAddress: string);
|
||||
ensureAdminIsSecured();
|
||||
loadSysPackages(core: IGBCoreService): Promise<IGBPackage[]>;
|
||||
ensureProxy(port): Promise<string>;
|
||||
ensureInstances(instances: IGBInstance[], bootInstance: any, core: IGBCoreService);
|
||||
checkStorage(azureDeployer: IGBInstallationDeployer);
|
||||
saveInstance(fullInstance: any);
|
||||
loadAllInstances(core: IGBCoreService, azureDeployer: IGBInstallationDeployer, proxyAddress: string);
|
||||
openBrowserInDevelopment();
|
||||
installWebHook(isGet: boolean, url: string, callback: any);
|
||||
setWWWRoot(localPath: string);
|
||||
setEntryPointDialog(dialogName: string);
|
||||
getParam<T>(instance: IGBInstance, name: string, defaultValue?: T): any;
|
||||
}
|
||||
|
|
@ -1,44 +0,0 @@
|
|||
/*****************************************************************************\
|
||||
| █████ █████ ██ █ █████ █████ ████ ██ ████ █████ █████ ███ ® |
|
||||
| ██ █ ███ █ █ ██ ██ ██ ██ ██ ██ █ ██ ██ █ █ |
|
||||
| ██ ███ ████ █ ██ █ ████ █████ ██████ ██ ████ █ █ █ ██ |
|
||||
| ██ ██ █ █ ██ █ █ ██ ██ ██ ██ ██ ██ █ ██ ██ █ █ |
|
||||
| █████ █████ █ ███ █████ ██ ██ ██ ██ █████ ████ █████ █ ███ |
|
||||
| |
|
||||
| General Bots Copyright (c) pragmatismo.cloud. All rights reserved. |
|
||||
| Licensed under the AGPL-3.0. |
|
||||
| |
|
||||
| According to our dual licensing model, this program can be used either |
|
||||
| under the terms of the GNU Affero General Public License, version 3, |
|
||||
| or under a proprietary license. |
|
||||
| |
|
||||
| The texts of the GNU Affero General Public License with an additional |
|
||||
| permission and of our proprietary license can be found at and |
|
||||
| in the LICENSE file you have received along with this program. |
|
||||
| |
|
||||
| This program is distributed in the hope that it will be useful, |
|
||||
| but WITHOUT ANY WARRANTY, without even the implied warranty of |
|
||||
| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|
||||
| GNU Affero General Public License for more details. |
|
||||
| |
|
||||
| "General Bots" is a registered trademark of pragmatismo.cloud. |
|
||||
| The licensing of the program under the AGPLv3 does not imply a |
|
||||
| trademark license. Therefore any rights, title and interest in |
|
||||
| our trademarks remain entirely with us. |
|
||||
| |
|
||||
\*****************************************************************************/
|
||||
|
||||
"use strict";
|
||||
|
||||
import { IGBInstance } from ".";
|
||||
import { GBMinInstance } from "./GBMinInstance";
|
||||
|
||||
export interface IGBDeployer {
|
||||
undeployPackageFromLocalPath(instance: IGBInstance, localPath: string): Promise<void>;
|
||||
deployPackage(min: GBMinInstance, localPath: string): Promise<void>;
|
||||
deployBlankBot(botId: string, mobile: string, email: string): Promise<IGBInstance>;
|
||||
botExists(botId: string): Promise<Boolean>;
|
||||
rebuildIndex(instance: IGBInstance, searchSchema: any): Promise<void>;
|
||||
refreshNLPEntity(instance: IGBInstance, listName, listData): Promise<void>;
|
||||
getBotManifest(instance: IGBInstance): Promise<Buffer>;
|
||||
}
|
||||
|
|
@ -1,41 +0,0 @@
|
|||
/*****************************************************************************\
|
||||
| █████ █████ ██ █ █████ █████ ████ ██ ████ █████ █████ ███ ® |
|
||||
| ██ █ ███ █ █ ██ ██ ██ ██ ██ ██ █ ██ ██ █ █ |
|
||||
| ██ ███ ████ █ ██ █ ████ █████ ██████ ██ ████ █ █ █ ██ |
|
||||
| ██ ██ █ █ ██ █ █ ██ ██ ██ ██ ██ ██ █ ██ ██ █ █ |
|
||||
| █████ █████ █ ███ █████ ██ ██ ██ ██ █████ ████ █████ █ ███ |
|
||||
| |
|
||||
| General Bots Copyright (c) pragmatismo.cloud. All rights reserved. |
|
||||
| Licensed under the AGPL-3.0. |
|
||||
| |
|
||||
| According to our dual licensing model, this program can be used either |
|
||||
| under the terms of the GNU Affero General Public License, version 3, |
|
||||
| or under a proprietary license. |
|
||||
| |
|
||||
| The texts of the GNU Affero General Public License with an additional |
|
||||
| permission and of our proprietary license can be found at and |
|
||||
| in the LICENSE file you have received along with this program. |
|
||||
| |
|
||||
| This program is distributed in the hope that it will be useful, |
|
||||
| but WITHOUT ANY WARRANTY, without even the implied warranty of |
|
||||
| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|
||||
| GNU Affero General Public License for more details. |
|
||||
| |
|
||||
| "General Bots" is a registered trademark of pragmatismo.cloud. |
|
||||
| The licensing of the program under the AGPLv3 does not imply a |
|
||||
| trademark license. Therefore any rights, title and interest in |
|
||||
| our trademarks remain entirely with us. |
|
||||
| |
|
||||
\*****************************************************************************/
|
||||
|
||||
"use strict"
|
||||
|
||||
import { BotAdapter } from "botbuilder"
|
||||
import { GBService } from "./GBService"
|
||||
|
||||
export class IGBDialog {
|
||||
bot: BotAdapter
|
||||
service: GBService
|
||||
constructor(bot: BotAdapter) {
|
||||
}
|
||||
}
|
||||
|
|
@ -1,57 +0,0 @@
|
|||
/*****************************************************************************\
|
||||
| █████ █████ ██ █ █████ █████ ████ ██ ████ █████ █████ ███ ® |
|
||||
| ██ █ ███ █ █ ██ ██ ██ ██ ██ ██ █ ██ ██ █ █ |
|
||||
| ██ ███ ████ █ ██ █ ████ █████ ██████ ██ ████ █ █ █ ██ |
|
||||
| ██ ██ █ █ ██ █ █ ██ ██ ██ ██ ██ ██ █ ██ ██ █ █ |
|
||||
| █████ █████ █ ███ █████ ██ ██ ██ ██ █████ ████ █████ █ ███ |
|
||||
| |
|
||||
| General Bots Copyright (c) pragmatismo.cloud. All rights reserved. |
|
||||
| Licensed under the AGPL-3.0. |
|
||||
| |
|
||||
| According to our dual licensing model, this program can be used either |
|
||||
| under the terms of the GNU Affero General Public License, version 3, |
|
||||
| or under a proprietary license. |
|
||||
| |
|
||||
| The texts of the GNU Affero General Public License with an additional |
|
||||
| permission and of our proprietary license can be found at and |
|
||||
| in the LICENSE file you have received along with this program. |
|
||||
| |
|
||||
| This program is distributed in the hope that it will be useful, |
|
||||
| but WITHOUT ANY WARRANTY, without even the implied warranty of |
|
||||
| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|
||||
| GNU Affero General Public License for more details. |
|
||||
| |
|
||||
| "General Bots" is a registered trademark of pragmatismo.cloud. |
|
||||
| The licensing of the program under the AGPLv3 does not imply a |
|
||||
| trademark license. Therefore any rights, title and interest in |
|
||||
| our trademarks remain entirely with us. |
|
||||
| |
|
||||
\*****************************************************************************/
|
||||
|
||||
"use strict";
|
||||
|
||||
import { IGBInstance } from "./IGBInstance";
|
||||
|
||||
export interface IGBInstallationDeployer {
|
||||
updateBotProxy(botId: string, group: string, endpoint: string);
|
||||
getSubscriptions(credentials);
|
||||
getKBSearchSchema(indexName);
|
||||
openStorageFirewall(groupName, serverName);
|
||||
createApplication(token: string, name: string);
|
||||
deployFarm(
|
||||
proxyAddress: string,
|
||||
instance: IGBInstance,
|
||||
credentials,
|
||||
subscriptionId: string
|
||||
): Promise<IGBInstance>;
|
||||
deployToCloud(
|
||||
title: string,
|
||||
username: string,
|
||||
password: string,
|
||||
cloudLocation: string,
|
||||
authoringKey: string,
|
||||
appId: string,
|
||||
appPassword: string,
|
||||
subscriptionId: string
|
||||
);
|
||||
}
|
||||
|
|
@ -1,101 +0,0 @@
|
|||
/*****************************************************************************\
|
||||
| █████ █████ ██ █ █████ █████ ████ ██ ████ █████ █████ ███ ® |
|
||||
| ██ █ ███ █ █ ██ ██ ██ ██ ██ ██ █ ██ ██ █ █ |
|
||||
| ██ ███ ████ █ ██ █ ████ █████ ██████ ██ ████ █ █ █ ██ |
|
||||
| ██ ██ █ █ ██ █ █ ██ ██ ██ ██ ██ ██ █ ██ ██ █ █ |
|
||||
| █████ █████ █ ███ █████ ██ ██ ██ ██ █████ ████ █████ █ ███ |
|
||||
| |
|
||||
| General Bots Copyright (c) pragmatismo.cloud. All rights reserved. |
|
||||
| Licensed under the AGPL-3.0. |
|
||||
| |
|
||||
| According to our dual licensing model, this program can be used either |
|
||||
| under the terms of the GNU Affero General Public License, version 3, |
|
||||
| or under a proprietary license. |
|
||||
| |
|
||||
| The texts of the GNU Affero General Public License with an additional |
|
||||
| permission and of our proprietary license can be found at and |
|
||||
| in the LICENSE file you have received along with this program. |
|
||||
| |
|
||||
| This program is distributed in the hope that it will be useful, |
|
||||
| but WITHOUT ANY WARRANTY, without even the implied warranty of |
|
||||
| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|
||||
| GNU Affero General Public License for more details. |
|
||||
| |
|
||||
| "General Bots" is a registered trademark of pragmatismo.cloud. |
|
||||
| The licensing of the program under the AGPLv3 does not imply a |
|
||||
| trademark license. Therefore any rights, title and interest in |
|
||||
| our trademarks remain entirely with us. |
|
||||
| |
|
||||
\*****************************************************************************/
|
||||
|
||||
"use strict";
|
||||
|
||||
export interface IGBInstance {
|
||||
botId: string;
|
||||
whoAmIVideo: string;
|
||||
botEndpoint: string;
|
||||
authenticatorTenant: string;
|
||||
authenticatorAuthorityHostUrl: string;
|
||||
cloudSubscriptionId: string;
|
||||
cloudUsername: string;
|
||||
cloudPassword: string;
|
||||
cloudLocation: string;
|
||||
instanceId: number;
|
||||
title: string;
|
||||
activationCode: string;
|
||||
description: string;
|
||||
version: string;
|
||||
enabledAdmin: boolean;
|
||||
engineName: string;
|
||||
marketplaceId: string;
|
||||
textAnalyticsKey: string;
|
||||
textAnalyticsEndpoint: string;
|
||||
marketplacePassword: string;
|
||||
webchatKey: string;
|
||||
googleBotKey: string;
|
||||
googleChatApiKey: string;
|
||||
googleChatSubscriptionName: string;
|
||||
googleClientEmail: string;
|
||||
googlePrivateKey: string;
|
||||
googleProjectId: string;
|
||||
whatsappServiceKey: string;
|
||||
whatsappBotKey: string;
|
||||
whatsappServiceNumber: string;
|
||||
whatsappServiceUrl: string;
|
||||
facebookWorkplaceVerifyToken: string;
|
||||
facebookWorkplaceAppSecret: string;
|
||||
facebookWorkplaceAccessToken: string;
|
||||
smsKey: string;
|
||||
smsSecret: string;
|
||||
smsServiceNumber: string;
|
||||
theme: string;
|
||||
ui: string;
|
||||
kb: string;
|
||||
nlpAppId: string;
|
||||
nlpKey: string;
|
||||
nlpEndpoint: string;
|
||||
nlpAuthoringKey: string;
|
||||
deploymentPaths: string;
|
||||
speechKey: string;
|
||||
speechEndpoint: string;
|
||||
spellcheckerKey: string;
|
||||
spellcheckerEndpoint: string;
|
||||
searchHost: string;
|
||||
searchKey: string;
|
||||
searchIndex: string;
|
||||
searchIndexer: string;
|
||||
searchScore: number;
|
||||
nlpScore: number;
|
||||
storageUsername: string;
|
||||
storagePassword: string;
|
||||
storageName: string;
|
||||
storageServer: string;
|
||||
storageDialect: string;
|
||||
storagePath: string;
|
||||
adminPass: string;
|
||||
translatorKey: string;
|
||||
translatorEndpoint: string;
|
||||
params: string;
|
||||
state: string;
|
||||
|
||||
}
|
||||
|
|
@ -1,35 +0,0 @@
|
|||
/*****************************************************************************\
|
||||
| █████ █████ ██ █ █████ █████ ████ ██ ████ █████ █████ ███ ® |
|
||||
| ██ █ ███ █ █ ██ ██ ██ ██ ██ ██ █ ██ ██ █ █ |
|
||||
| ██ ███ ████ █ ██ █ ████ █████ ██████ ██ ████ █ █ █ ██ |
|
||||
| ██ ██ █ █ ██ █ █ ██ ██ ██ ██ ██ ██ █ ██ ██ █ █ |
|
||||
| █████ █████ █ ███ █████ ██ ██ ██ ██ █████ ████ █████ █ ███ |
|
||||
| |
|
||||
| General Bots Copyright (c) pragmatismo.cloud. All rights reserved. |
|
||||
| Licensed under the AGPL-3.0. |
|
||||
| |
|
||||
| According to our dual licensing model, this program can be used either |
|
||||
| under the terms of the GNU Affero General Public License, version 3, |
|
||||
| or under a proprietary license. |
|
||||
| |
|
||||
| The texts of the GNU Affero General Public License with an additional |
|
||||
| permission and of our proprietary license can be found at and |
|
||||
| in the LICENSE file you have received along with this program. |
|
||||
| |
|
||||
| This program is distributed in the hope that it will be useful, |
|
||||
| but WITHOUT ANY WARRANTY, without even the implied warranty of |
|
||||
| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|
||||
| GNU Affero General Public License for more details. |
|
||||
| |
|
||||
| "General Bots" is a registered trademark of pragmatismo.cloud. |
|
||||
| The licensing of the program under the AGPLv3 does not imply a |
|
||||
| trademark license. Therefore any rights, title and interest in |
|
||||
| our trademarks remain entirely with us. |
|
||||
| |
|
||||
\*****************************************************************************/
|
||||
|
||||
"use strict";
|
||||
|
||||
export interface IGBKBService {
|
||||
getAnswerTextByMediaName(instanceId: number, answerMediaName: string): Promise<string>;
|
||||
}
|
||||
|
|
@ -1,82 +0,0 @@
|
|||
/*****************************************************************************\
|
||||
| █████ █████ ██ █ █████ █████ ████ ██ ████ █████ █████ ███ ® |
|
||||
| ██ █ ███ █ █ ██ ██ ██ ██ ██ ██ █ ██ ██ █ █ |
|
||||
| ██ ███ ████ █ ██ █ ████ █████ ██████ ██ ████ █ █ █ ██ |
|
||||
| ██ ██ █ █ ██ █ █ ██ ██ ██ ██ ██ ██ █ ██ ██ █ █ |
|
||||
| █████ █████ █ ███ █████ ██ ██ ██ ██ █████ ████ █████ █ ███ |
|
||||
| |
|
||||
| General Bots Copyright (c) pragmatismo.cloud. All rights reserved. |
|
||||
| Licensed under the AGPL-3.0. |
|
||||
| |
|
||||
| According to our dual licensing model, this program can be used either |
|
||||
| under the terms of the GNU Affero General Public License, version 3, |
|
||||
| or under a proprietary license. |
|
||||
| |
|
||||
| The texts of the GNU Affero General Public License with an additional |
|
||||
| permission and of our proprietary license can be found at and |
|
||||
| in the LICENSE file you have received along with this program. |
|
||||
| |
|
||||
| This program is distributed in the hope that it will be useful, |
|
||||
| but WITHOUT ANY WARRANTY, without even the implied warranty of |
|
||||
| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|
||||
| GNU Affero General Public License for more details. |
|
||||
| |
|
||||
| "General Bots" is a registered trademark of pragmatismo.cloud. |
|
||||
| The licensing of the program under the AGPLv3 does not imply a |
|
||||
| trademark license. Therefore any rights, title and interest in |
|
||||
| our trademarks remain entirely with us. |
|
||||
| |
|
||||
\*****************************************************************************/
|
||||
|
||||
'use strict';
|
||||
|
||||
import { IGBCoreService } from './IGBCoreService'
|
||||
import { Sequelize } from 'sequelize-typescript'
|
||||
import { GBMinInstance } from '.'
|
||||
import { GBDialogStep } from './GBDialogStep';
|
||||
|
||||
export interface IGBPackage{
|
||||
|
||||
/**
|
||||
* Each app has its own set of sys packages.
|
||||
*/
|
||||
sysPackages: IGBPackage[]
|
||||
|
||||
/**
|
||||
* Called when a package is being loaded, once per server or at demand.
|
||||
*/
|
||||
loadPackage(core: IGBCoreService, sequelize: Sequelize): Promise<void>
|
||||
|
||||
/**
|
||||
* Called when a package needs to be unloaded.
|
||||
*/
|
||||
unloadPackage(core: IGBCoreService): Promise<void>
|
||||
|
||||
/**
|
||||
* Called when a new bot instance is loaded.
|
||||
*/
|
||||
getDialogs(min: GBMinInstance)
|
||||
|
||||
/**
|
||||
* Called when a new bot instance is loaded.
|
||||
*/
|
||||
loadBot(min: GBMinInstance): Promise<void>
|
||||
|
||||
/**
|
||||
* Called whenever a bot instance needs to be shutdown.
|
||||
*/
|
||||
unloadBot(min: GBMinInstance): Promise<void>
|
||||
|
||||
/**
|
||||
* Called in each new session.
|
||||
*/
|
||||
onNewSession(min: GBMinInstance, step: GBDialogStep): Promise<void>
|
||||
|
||||
/**
|
||||
* Exchange data between BotServer and .gbapp/.gblib
|
||||
* @param kind 'newMessage', 'getBroadcast', 'getKeywords'
|
||||
* @param data
|
||||
*/
|
||||
onExchangeData (min: GBMinInstance, kind: string, data: any);
|
||||
|
||||
}
|
||||
326
src/branding.rs
Normal file
326
src/branding.rs
Normal file
|
|
@ -0,0 +1,326 @@
|
|||
//! White-Label Branding Module
|
||||
//!
|
||||
//! Allows complete customization of platform identity.
|
||||
//! When a .product file exists with name=MyCustomPlatform,
|
||||
//! "General Bots" never appears in logs, display, messages, footer - nothing.
|
||||
|
||||
use log::info;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use std::path::Path;
|
||||
use std::sync::OnceLock;
|
||||
|
||||
/// Global branding configuration - loaded once at startup
|
||||
static BRANDING: OnceLock<BrandingConfig> = OnceLock::new();
|
||||
|
||||
/// Default platform name
|
||||
const DEFAULT_PLATFORM_NAME: &str = "General Bots";
|
||||
const DEFAULT_PLATFORM_SHORT: &str = "GB";
|
||||
const DEFAULT_PLATFORM_DOMAIN: &str = "generalbots.com";
|
||||
|
||||
/// Branding configuration loaded from .product file
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
pub struct BrandingConfig {
|
||||
/// Platform name (e.g., "MyCustomPlatform")
|
||||
pub name: String,
|
||||
/// Short name for logs and compact displays (e.g., "MCP")
|
||||
pub short_name: String,
|
||||
/// Company/organization name
|
||||
pub company: Option<String>,
|
||||
/// Domain for URLs and emails
|
||||
pub domain: Option<String>,
|
||||
/// Support email
|
||||
pub support_email: Option<String>,
|
||||
/// Logo URL (for web UI)
|
||||
pub logo_url: Option<String>,
|
||||
/// Favicon URL
|
||||
pub favicon_url: Option<String>,
|
||||
/// Primary color (hex)
|
||||
pub primary_color: Option<String>,
|
||||
/// Secondary color (hex)
|
||||
pub secondary_color: Option<String>,
|
||||
/// Footer text
|
||||
pub footer_text: Option<String>,
|
||||
/// Copyright text
|
||||
pub copyright: Option<String>,
|
||||
/// Custom CSS URL
|
||||
pub custom_css: Option<String>,
|
||||
/// Terms of service URL
|
||||
pub terms_url: Option<String>,
|
||||
/// Privacy policy URL
|
||||
pub privacy_url: Option<String>,
|
||||
/// Documentation URL
|
||||
pub docs_url: Option<String>,
|
||||
/// Whether this is a white-label deployment
|
||||
pub is_white_label: bool,
|
||||
}
|
||||
|
||||
impl Default for BrandingConfig {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
name: DEFAULT_PLATFORM_NAME.to_string(),
|
||||
short_name: DEFAULT_PLATFORM_SHORT.to_string(),
|
||||
company: Some("pragmatismo.com.br".to_string()),
|
||||
domain: Some(DEFAULT_PLATFORM_DOMAIN.to_string()),
|
||||
support_email: Some("support@generalbots.com".to_string()),
|
||||
logo_url: None,
|
||||
favicon_url: None,
|
||||
primary_color: Some("#25d366".to_string()),
|
||||
secondary_color: Some("#075e54".to_string()),
|
||||
footer_text: None,
|
||||
copyright: Some(format!(
|
||||
"© {} pragmatismo.com.br. All rights reserved.",
|
||||
chrono::Utc::now().format("%Y")
|
||||
)),
|
||||
custom_css: None,
|
||||
terms_url: None,
|
||||
privacy_url: None,
|
||||
docs_url: Some("https://docs.generalbots.com".to_string()),
|
||||
is_white_label: false,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl BrandingConfig {
|
||||
/// Load branding from .product file if it exists
|
||||
pub fn load() -> Self {
|
||||
let search_paths = [
|
||||
".product",
|
||||
"config/.product",
|
||||
"/etc/botserver/.product",
|
||||
"/opt/gbo/.product",
|
||||
];
|
||||
|
||||
for path in &search_paths {
|
||||
if let Ok(config) = Self::load_from_file(path) {
|
||||
info!("Loaded white-label branding from {}: {}", path, config.name);
|
||||
return config;
|
||||
}
|
||||
}
|
||||
|
||||
// Check environment variable
|
||||
if let Ok(product_file) = std::env::var("PRODUCT_FILE") {
|
||||
if let Ok(config) = Self::load_from_file(&product_file) {
|
||||
info!(
|
||||
"Loaded white-label branding from PRODUCT_FILE={}: {}",
|
||||
product_file, config.name
|
||||
);
|
||||
return config;
|
||||
}
|
||||
}
|
||||
|
||||
// Check for individual environment overrides
|
||||
let mut config = Self::default();
|
||||
|
||||
if let Ok(name) = std::env::var("PLATFORM_NAME") {
|
||||
config.name = name;
|
||||
config.is_white_label = true;
|
||||
}
|
||||
if let Ok(short) = std::env::var("PLATFORM_SHORT_NAME") {
|
||||
config.short_name = short;
|
||||
}
|
||||
if let Ok(company) = std::env::var("PLATFORM_COMPANY") {
|
||||
config.company = Some(company);
|
||||
}
|
||||
if let Ok(domain) = std::env::var("PLATFORM_DOMAIN") {
|
||||
config.domain = Some(domain);
|
||||
}
|
||||
if let Ok(logo) = std::env::var("PLATFORM_LOGO_URL") {
|
||||
config.logo_url = Some(logo);
|
||||
}
|
||||
if let Ok(color) = std::env::var("PLATFORM_PRIMARY_COLOR") {
|
||||
config.primary_color = Some(color);
|
||||
}
|
||||
|
||||
config
|
||||
}
|
||||
|
||||
/// Load from a specific file path
|
||||
fn load_from_file(path: &str) -> Result<Self, Box<dyn std::error::Error>> {
|
||||
let path = Path::new(path);
|
||||
if !path.exists() {
|
||||
return Err("File not found".into());
|
||||
}
|
||||
|
||||
let content = std::fs::read_to_string(path)?;
|
||||
|
||||
// Try parsing as TOML first
|
||||
if let Ok(config) = toml::from_str::<ProductFile>(&content) {
|
||||
return Ok(config.into());
|
||||
}
|
||||
|
||||
// Try parsing as simple key=value format
|
||||
let mut config = Self::default();
|
||||
config.is_white_label = true;
|
||||
|
||||
for line in content.lines() {
|
||||
let line = line.trim();
|
||||
if line.is_empty() || line.starts_with('#') || line.starts_with(';') {
|
||||
continue;
|
||||
}
|
||||
|
||||
if let Some((key, value)) = line.split_once('=') {
|
||||
let key = key.trim().to_lowercase();
|
||||
let value = value.trim().trim_matches('"').trim_matches('\'');
|
||||
|
||||
match key.as_str() {
|
||||
"name" | "platform_name" => config.name = value.to_string(),
|
||||
"short_name" | "short" => config.short_name = value.to_string(),
|
||||
"company" | "organization" => config.company = Some(value.to_string()),
|
||||
"domain" => config.domain = Some(value.to_string()),
|
||||
"support_email" | "email" => config.support_email = Some(value.to_string()),
|
||||
"logo_url" | "logo" => config.logo_url = Some(value.to_string()),
|
||||
"favicon_url" | "favicon" => config.favicon_url = Some(value.to_string()),
|
||||
"primary_color" | "color" => config.primary_color = Some(value.to_string()),
|
||||
"secondary_color" => config.secondary_color = Some(value.to_string()),
|
||||
"footer_text" | "footer" => config.footer_text = Some(value.to_string()),
|
||||
"copyright" => config.copyright = Some(value.to_string()),
|
||||
"custom_css" | "css" => config.custom_css = Some(value.to_string()),
|
||||
"terms_url" | "terms" => config.terms_url = Some(value.to_string()),
|
||||
"privacy_url" | "privacy" => config.privacy_url = Some(value.to_string()),
|
||||
"docs_url" | "docs" => config.docs_url = Some(value.to_string()),
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Ok(config)
|
||||
}
|
||||
}
|
||||
|
||||
/// TOML format for .product file
|
||||
#[derive(Debug, Deserialize)]
|
||||
struct ProductFile {
|
||||
name: String,
|
||||
#[serde(default)]
|
||||
short_name: Option<String>,
|
||||
#[serde(default)]
|
||||
company: Option<String>,
|
||||
#[serde(default)]
|
||||
domain: Option<String>,
|
||||
#[serde(default)]
|
||||
support_email: Option<String>,
|
||||
#[serde(default)]
|
||||
logo_url: Option<String>,
|
||||
#[serde(default)]
|
||||
favicon_url: Option<String>,
|
||||
#[serde(default)]
|
||||
primary_color: Option<String>,
|
||||
#[serde(default)]
|
||||
secondary_color: Option<String>,
|
||||
#[serde(default)]
|
||||
footer_text: Option<String>,
|
||||
#[serde(default)]
|
||||
copyright: Option<String>,
|
||||
#[serde(default)]
|
||||
custom_css: Option<String>,
|
||||
#[serde(default)]
|
||||
terms_url: Option<String>,
|
||||
#[serde(default)]
|
||||
privacy_url: Option<String>,
|
||||
#[serde(default)]
|
||||
docs_url: Option<String>,
|
||||
}
|
||||
|
||||
impl From<ProductFile> for BrandingConfig {
|
||||
fn from(pf: ProductFile) -> Self {
|
||||
let short_name = pf.short_name.unwrap_or_else(|| {
|
||||
pf.name
|
||||
.split_whitespace()
|
||||
.map(|w| w.chars().next().unwrap_or('X'))
|
||||
.collect::<String>()
|
||||
.to_uppercase()
|
||||
});
|
||||
|
||||
Self {
|
||||
name: pf.name,
|
||||
short_name,
|
||||
company: pf.company,
|
||||
domain: pf.domain,
|
||||
support_email: pf.support_email,
|
||||
logo_url: pf.logo_url,
|
||||
favicon_url: pf.favicon_url,
|
||||
primary_color: pf.primary_color,
|
||||
secondary_color: pf.secondary_color,
|
||||
footer_text: pf.footer_text,
|
||||
copyright: pf.copyright,
|
||||
custom_css: pf.custom_css,
|
||||
terms_url: pf.terms_url,
|
||||
privacy_url: pf.privacy_url,
|
||||
docs_url: pf.docs_url,
|
||||
is_white_label: true,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
// Global Access Functions
|
||||
// ============================================================================
|
||||
|
||||
/// Initialize branding at application startup
|
||||
pub fn init_branding() {
|
||||
let config = BrandingConfig::load();
|
||||
let _ = BRANDING.set(config);
|
||||
}
|
||||
|
||||
/// Get the current branding configuration
|
||||
pub fn branding() -> &'static BrandingConfig {
|
||||
BRANDING.get_or_init(BrandingConfig::load)
|
||||
}
|
||||
|
||||
/// Get the platform name
|
||||
pub fn platform_name() -> &'static str {
|
||||
&branding().name
|
||||
}
|
||||
|
||||
/// Get the short platform name
|
||||
pub fn platform_short() -> &'static str {
|
||||
&branding().short_name
|
||||
}
|
||||
|
||||
/// Check if this is a white-label deployment
|
||||
pub fn is_white_label() -> bool {
|
||||
branding().is_white_label
|
||||
}
|
||||
|
||||
/// Get formatted copyright text
|
||||
pub fn copyright_text() -> String {
|
||||
branding().copyright.clone().unwrap_or_else(|| {
|
||||
format!(
|
||||
"© {} {}",
|
||||
chrono::Utc::now().format("%Y"),
|
||||
branding().company.as_deref().unwrap_or(&branding().name)
|
||||
)
|
||||
})
|
||||
}
|
||||
|
||||
/// Get footer text
|
||||
pub fn footer_text() -> String {
|
||||
branding()
|
||||
.footer_text
|
||||
.clone()
|
||||
.unwrap_or_else(|| format!("Powered by {}", platform_name()))
|
||||
}
|
||||
|
||||
/// Format a log prefix with platform branding
|
||||
pub fn log_prefix() -> String {
|
||||
format!("[{}]", platform_short())
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn test_default_branding() {
|
||||
let config = BrandingConfig::default();
|
||||
assert_eq!(config.name, "General Bots");
|
||||
assert_eq!(config.short_name, "GB");
|
||||
assert!(!config.is_white_label);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_platform_name_function() {
|
||||
let name = platform_name();
|
||||
assert!(!name.is_empty());
|
||||
}
|
||||
}
|
||||
131
src/error.rs
Normal file
131
src/error.rs
Normal file
|
|
@ -0,0 +1,131 @@
|
|||
//! Common error types for BotLib
|
||||
//!
|
||||
//! Provides unified error handling across botserver and botui.
|
||||
|
||||
use thiserror::Error;
|
||||
|
||||
/// Result type alias using BotError
|
||||
pub type BotResult<T> = Result<T, BotError>;
|
||||
|
||||
/// Common error types across the bot ecosystem
|
||||
#[derive(Error, Debug)]
|
||||
pub enum BotError {
|
||||
/// Configuration errors
|
||||
#[error("Configuration error: {0}")]
|
||||
Config(String),
|
||||
|
||||
/// Database errors
|
||||
#[error("Database error: {0}")]
|
||||
Database(String),
|
||||
|
||||
/// HTTP/Network errors
|
||||
#[error("HTTP error: {0}")]
|
||||
Http(String),
|
||||
|
||||
/// Authentication/Authorization errors
|
||||
#[error("Auth error: {0}")]
|
||||
Auth(String),
|
||||
|
||||
/// Validation errors
|
||||
#[error("Validation error: {0}")]
|
||||
Validation(String),
|
||||
|
||||
/// Not found errors
|
||||
#[error("{0} not found")]
|
||||
NotFound(String),
|
||||
|
||||
/// Internal errors
|
||||
#[error("Internal error: {0}")]
|
||||
Internal(String),
|
||||
|
||||
/// IO errors
|
||||
#[error("IO error: {0}")]
|
||||
Io(#[from] std::io::Error),
|
||||
|
||||
/// JSON serialization errors
|
||||
#[error("JSON error: {0}")]
|
||||
Json(#[from] serde_json::Error),
|
||||
|
||||
/// Generic error wrapper
|
||||
#[error("{0}")]
|
||||
Other(String),
|
||||
}
|
||||
|
||||
impl BotError {
|
||||
/// Create a config error
|
||||
pub fn config(msg: impl Into<String>) -> Self {
|
||||
Self::Config(msg.into())
|
||||
}
|
||||
|
||||
/// Create a database error
|
||||
pub fn database(msg: impl Into<String>) -> Self {
|
||||
Self::Database(msg.into())
|
||||
}
|
||||
|
||||
/// Create an HTTP error
|
||||
pub fn http(msg: impl Into<String>) -> Self {
|
||||
Self::Http(msg.into())
|
||||
}
|
||||
|
||||
/// Create an auth error
|
||||
pub fn auth(msg: impl Into<String>) -> Self {
|
||||
Self::Auth(msg.into())
|
||||
}
|
||||
|
||||
/// Create a validation error
|
||||
pub fn validation(msg: impl Into<String>) -> Self {
|
||||
Self::Validation(msg.into())
|
||||
}
|
||||
|
||||
/// Create a not found error
|
||||
pub fn not_found(entity: impl Into<String>) -> Self {
|
||||
Self::NotFound(entity.into())
|
||||
}
|
||||
|
||||
/// Create an internal error
|
||||
pub fn internal(msg: impl Into<String>) -> Self {
|
||||
Self::Internal(msg.into())
|
||||
}
|
||||
}
|
||||
|
||||
impl From<anyhow::Error> for BotError {
|
||||
fn from(err: anyhow::Error) -> Self {
|
||||
Self::Other(err.to_string())
|
||||
}
|
||||
}
|
||||
|
||||
impl From<String> for BotError {
|
||||
fn from(msg: String) -> Self {
|
||||
Self::Other(msg)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<&str> for BotError {
|
||||
fn from(msg: &str) -> Self {
|
||||
Self::Other(msg.to_string())
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "http-client")]
|
||||
impl From<reqwest::Error> for BotError {
|
||||
fn from(err: reqwest::Error) -> Self {
|
||||
Self::Http(err.to_string())
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn test_error_display() {
|
||||
let err = BotError::config("missing API key");
|
||||
assert_eq!(err.to_string(), "Configuration error: missing API key");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_not_found_error() {
|
||||
let err = BotError::not_found("User");
|
||||
assert_eq!(err.to_string(), "User not found");
|
||||
}
|
||||
}
|
||||
239
src/http_client.rs
Normal file
239
src/http_client.rs
Normal file
|
|
@ -0,0 +1,239 @@
|
|||
//! HTTP client for communicating with botserver
|
||||
//!
|
||||
//! Provides a reusable HTTP client for API calls.
|
||||
|
||||
use crate::error::BotError;
|
||||
use log::{debug, error};
|
||||
use serde::{de::DeserializeOwned, Serialize};
|
||||
use std::sync::Arc;
|
||||
use std::time::Duration;
|
||||
|
||||
/// HTTP client for communicating with botserver
|
||||
#[derive(Clone)]
|
||||
pub struct BotServerClient {
|
||||
client: Arc<reqwest::Client>,
|
||||
base_url: String,
|
||||
}
|
||||
|
||||
impl BotServerClient {
|
||||
/// Create new botserver HTTP client
|
||||
pub fn new(base_url: Option<String>) -> Self {
|
||||
let url = base_url.unwrap_or_else(|| {
|
||||
std::env::var("BOTSERVER_URL").unwrap_or_else(|_| "https://localhost:8088".to_string())
|
||||
});
|
||||
|
||||
let client = reqwest::Client::builder()
|
||||
.timeout(Duration::from_secs(30))
|
||||
.user_agent(format!("BotLib/{}", env!("CARGO_PKG_VERSION")))
|
||||
.danger_accept_invalid_certs(true) // Accept self-signed certs for local dev
|
||||
.build()
|
||||
.expect("Failed to create HTTP client");
|
||||
|
||||
Self {
|
||||
client: Arc::new(client),
|
||||
base_url: url,
|
||||
}
|
||||
}
|
||||
|
||||
/// Create with custom timeout
|
||||
pub fn with_timeout(base_url: Option<String>, timeout: Duration) -> Self {
|
||||
let url = base_url.unwrap_or_else(|| {
|
||||
std::env::var("BOTSERVER_URL").unwrap_or_else(|_| "http://localhost:8080".to_string())
|
||||
});
|
||||
|
||||
let client = reqwest::Client::builder()
|
||||
.timeout(timeout)
|
||||
.user_agent(format!("BotLib/{}", env!("CARGO_PKG_VERSION")))
|
||||
.build()
|
||||
.expect("Failed to create HTTP client");
|
||||
|
||||
Self {
|
||||
client: Arc::new(client),
|
||||
base_url: url,
|
||||
}
|
||||
}
|
||||
|
||||
/// Get the base URL
|
||||
pub fn base_url(&self) -> &str {
|
||||
&self.base_url
|
||||
}
|
||||
|
||||
/// GET request
|
||||
pub async fn get<T: DeserializeOwned>(&self, endpoint: &str) -> Result<T, BotError> {
|
||||
let url = format!("{}{}", self.base_url, endpoint);
|
||||
debug!("GET {}", url);
|
||||
|
||||
let response = self.client.get(&url).send().await?;
|
||||
self.handle_response(response).await
|
||||
}
|
||||
|
||||
/// POST request with body
|
||||
pub async fn post<T: Serialize, R: DeserializeOwned>(
|
||||
&self,
|
||||
endpoint: &str,
|
||||
body: &T,
|
||||
) -> Result<R, BotError> {
|
||||
let url = format!("{}{}", self.base_url, endpoint);
|
||||
debug!("POST {}", url);
|
||||
|
||||
let response = self.client.post(&url).json(body).send().await?;
|
||||
self.handle_response(response).await
|
||||
}
|
||||
|
||||
/// PUT request with body
|
||||
pub async fn put<T: Serialize, R: DeserializeOwned>(
|
||||
&self,
|
||||
endpoint: &str,
|
||||
body: &T,
|
||||
) -> Result<R, BotError> {
|
||||
let url = format!("{}{}", self.base_url, endpoint);
|
||||
debug!("PUT {}", url);
|
||||
|
||||
let response = self.client.put(&url).json(body).send().await?;
|
||||
self.handle_response(response).await
|
||||
}
|
||||
|
||||
/// PATCH request with body
|
||||
pub async fn patch<T: Serialize, R: DeserializeOwned>(
|
||||
&self,
|
||||
endpoint: &str,
|
||||
body: &T,
|
||||
) -> Result<R, BotError> {
|
||||
let url = format!("{}{}", self.base_url, endpoint);
|
||||
debug!("PATCH {}", url);
|
||||
|
||||
let response = self.client.patch(&url).json(body).send().await?;
|
||||
self.handle_response(response).await
|
||||
}
|
||||
|
||||
/// DELETE request
|
||||
pub async fn delete<T: DeserializeOwned>(&self, endpoint: &str) -> Result<T, BotError> {
|
||||
let url = format!("{}{}", self.base_url, endpoint);
|
||||
debug!("DELETE {}", url);
|
||||
|
||||
let response = self.client.delete(&url).send().await?;
|
||||
self.handle_response(response).await
|
||||
}
|
||||
|
||||
/// Handle response and deserialize
|
||||
async fn handle_response<T: DeserializeOwned>(
|
||||
&self,
|
||||
response: reqwest::Response,
|
||||
) -> Result<T, BotError> {
|
||||
let status = response.status();
|
||||
|
||||
if !status.is_success() {
|
||||
let error_text = response
|
||||
.text()
|
||||
.await
|
||||
.unwrap_or_else(|_| "Unknown error".to_string());
|
||||
error!("HTTP {} error: {}", status, error_text);
|
||||
return Err(BotError::http(format!("HTTP {}: {}", status, error_text)));
|
||||
}
|
||||
|
||||
response.json().await.map_err(|e| {
|
||||
error!("Failed to parse response: {}", e);
|
||||
BotError::http(format!("Failed to parse response: {}", e))
|
||||
})
|
||||
}
|
||||
|
||||
/// Check if botserver is healthy
|
||||
pub async fn health_check(&self) -> bool {
|
||||
match self.get::<serde_json::Value>("/health").await {
|
||||
Ok(_) => true,
|
||||
Err(e) => {
|
||||
error!("Health check failed: {}", e);
|
||||
false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// GET with bearer token authorization
|
||||
pub async fn get_authorized<T: DeserializeOwned>(
|
||||
&self,
|
||||
endpoint: &str,
|
||||
token: &str,
|
||||
) -> Result<T, BotError> {
|
||||
let url = format!("{}{}", self.base_url, endpoint);
|
||||
debug!("GET {} (authorized)", url);
|
||||
|
||||
let response = self.client.get(&url).bearer_auth(token).send().await?;
|
||||
self.handle_response(response).await
|
||||
}
|
||||
|
||||
/// POST with bearer token authorization
|
||||
pub async fn post_authorized<T: Serialize, R: DeserializeOwned>(
|
||||
&self,
|
||||
endpoint: &str,
|
||||
body: &T,
|
||||
token: &str,
|
||||
) -> Result<R, BotError> {
|
||||
let url = format!("{}{}", self.base_url, endpoint);
|
||||
debug!("POST {} (authorized)", url);
|
||||
|
||||
let response = self
|
||||
.client
|
||||
.post(&url)
|
||||
.bearer_auth(token)
|
||||
.json(body)
|
||||
.send()
|
||||
.await?;
|
||||
self.handle_response(response).await
|
||||
}
|
||||
|
||||
/// DELETE with bearer token authorization
|
||||
pub async fn delete_authorized<T: DeserializeOwned>(
|
||||
&self,
|
||||
endpoint: &str,
|
||||
token: &str,
|
||||
) -> Result<T, BotError> {
|
||||
let url = format!("{}{}", self.base_url, endpoint);
|
||||
debug!("DELETE {} (authorized)", url);
|
||||
|
||||
let response = self.client.delete(&url).bearer_auth(token).send().await?;
|
||||
self.handle_response(response).await
|
||||
}
|
||||
}
|
||||
|
||||
impl std::fmt::Debug for BotServerClient {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
f.debug_struct("BotServerClient")
|
||||
.field("base_url", &self.base_url)
|
||||
.finish()
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn test_client_creation() {
|
||||
let client = BotServerClient::new(Some("http://localhost:8080".to_string()));
|
||||
assert_eq!(client.base_url(), "http://localhost:8080");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_client_default_url() {
|
||||
std::env::remove_var("BOTSERVER_URL");
|
||||
let client = BotServerClient::new(None);
|
||||
assert_eq!(client.base_url(), "http://localhost:8080");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_client_with_timeout() {
|
||||
let client = BotServerClient::with_timeout(
|
||||
Some("http://test:9000".to_string()),
|
||||
Duration::from_secs(60),
|
||||
);
|
||||
assert_eq!(client.base_url(), "http://test:9000");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_client_debug() {
|
||||
let client = BotServerClient::new(Some("http://debug-test".to_string()));
|
||||
let debug_str = format!("{:?}", client);
|
||||
assert!(debug_str.contains("BotServerClient"));
|
||||
assert!(debug_str.contains("http://debug-test"));
|
||||
}
|
||||
}
|
||||
47
src/index.ts
47
src/index.ts
|
|
@ -1,47 +0,0 @@
|
|||
/*****************************************************************************\
|
||||
| █████ █████ ██ █ █████ █████ ████ ██ ████ █████ █████ ███ ® |
|
||||
| ██ █ ███ █ █ ██ ██ ██ ██ ██ ██ █ ██ ██ █ █ |
|
||||
| ██ ███ ████ █ ██ █ ████ █████ ██████ ██ ████ █ █ █ ██ |
|
||||
| ██ ██ █ █ ██ █ █ ██ ██ ██ ██ ██ ██ █ ██ ██ █ █ |
|
||||
| █████ █████ █ ███ █████ ██ ██ ██ ██ █████ ████ █████ █ ███ |
|
||||
| |
|
||||
| General Bots Copyright (c) pragmatismo.cloud. All rights reserved. |
|
||||
| Licensed under the AGPL-3.0. |
|
||||
| |
|
||||
| According to our dual licensing model, this program can be used either |
|
||||
| under the terms of the GNU Affero General Public License, version 3, |
|
||||
| or under a proprietary license. |
|
||||
| |
|
||||
| The texts of the GNU Affero General Public License with an additional |
|
||||
| permission and of our proprietary license can be found at and |
|
||||
| in the LICENSE file you have received along with this program. |
|
||||
| |
|
||||
| This program is distributed in the hope that it will be useful, |
|
||||
| but WITHOUT ANY WARRANTY, without even the implied warranty of |
|
||||
| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|
||||
| GNU Affero General Public License for more details. |
|
||||
| |
|
||||
| "General Bots" is a registered trademark of pragmatismo.cloud. |
|
||||
| The licensing of the program under the AGPLv3 does not imply a |
|
||||
| trademark license. Therefore any rights, title and interest in |
|
||||
| our trademarks remain entirely with us. |
|
||||
| |
|
||||
\*****************************************************************************/
|
||||
|
||||
"use strict";
|
||||
|
||||
export { Sequelize } from "sequelize-typescript";
|
||||
export { IGBConversationalService } from "./IGBConversationalService";
|
||||
export { IGBKBService } from "./IGBKBService";
|
||||
export { IGBCoreService } from "./IGBCoreService";
|
||||
export { IGBDialog } from "./IGBDialog";
|
||||
export { IGBPackage } from "./IGBPackage";
|
||||
export { IGBInstance } from "./IGBInstance";
|
||||
export { GBError, GBERROR_TYPE } from "./GBError";
|
||||
export { GBService } from "./GBService";
|
||||
export { GBMinInstance } from "./GBMinInstance";
|
||||
export { IGBAdminService } from "./IGBAdminService";
|
||||
export { IGBInstallationDeployer } from "./IGBInstallationDeployer";
|
||||
export { IGBDeployer } from "./IGBDeployer";
|
||||
export { GBDialogStep } from "./GBDialogStep";
|
||||
export { GBLog } from "./GBLog";
|
||||
30
src/lib.rs
Normal file
30
src/lib.rs
Normal file
|
|
@ -0,0 +1,30 @@
|
|||
//! BotLib - Shared library for General Bots
|
||||
//!
|
||||
//! This crate provides common types, utilities, and abstractions
|
||||
//! shared between botserver and botui.
|
||||
//!
|
||||
//! # Features
|
||||
//! - `database` - Database connection utilities (diesel)
|
||||
//! - `http-client` - HTTP client for API calls
|
||||
//! - `validation` - Request validation derive macros
|
||||
|
||||
pub mod branding;
|
||||
pub mod error;
|
||||
#[cfg(feature = "http-client")]
|
||||
pub mod http_client;
|
||||
pub mod message_types;
|
||||
pub mod models;
|
||||
pub mod version;
|
||||
|
||||
// Re-exports for convenience
|
||||
pub use branding::{branding, init_branding, is_white_label, platform_name, platform_short, BrandingConfig};
|
||||
pub use error::{BotError, BotResult};
|
||||
pub use message_types::MessageType;
|
||||
pub use models::{ApiResponse, BotResponse, Session, Suggestion, UserMessage};
|
||||
pub use version::{
|
||||
get_botserver_version, init_version_registry, register_component, version_string,
|
||||
ComponentSource, ComponentStatus, ComponentVersion, VersionRegistry, BOTSERVER_VERSION,
|
||||
};
|
||||
|
||||
#[cfg(feature = "http-client")]
|
||||
pub use http_client::BotServerClient;
|
||||
|
|
@ -1,82 +0,0 @@
|
|||
/*****************************************************************************\
|
||||
| █████ █████ ██ █ █████ █████ ████ ██ ████ █████ █████ ███ ® |
|
||||
| ██ █ ███ █ █ ██ ██ ██ ██ ██ ██ █ ██ ██ █ █ |
|
||||
| ██ ███ ████ █ ██ █ ████ █████ ██████ ██ ████ █ █ █ ██ |
|
||||
| ██ ██ █ █ ██ █ █ ██ ██ ██ ██ ██ ██ █ ██ ██ █ █ |
|
||||
| █████ █████ █ ███ █████ ██ ██ ██ ██ █████ ████ █████ █ ███ |
|
||||
| |
|
||||
| General Bots Copyright (c) pragmatismo.cloud. All rights reserved. |
|
||||
| Licensed under the AGPL-3.0. |
|
||||
| |
|
||||
| According to our dual licensing model, this program can be used either |
|
||||
| under the terms of the GNU Affero General Public License, version 3, |
|
||||
| or under a proprietary license. |
|
||||
| |
|
||||
| The texts of the GNU Affero General Public License with an additional |
|
||||
| permission and of our proprietary license can be found at and |
|
||||
| in the LICENSE file you have received along with this program. |
|
||||
| |
|
||||
| This program is distributed in the hope that it will be useful, |
|
||||
| but WITHOUT ANY WARRANTY, without even the implied warranty of |
|
||||
| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|
||||
| GNU Affero General Public License for more details. |
|
||||
| |
|
||||
| "General Bots" is a registered trademark of pragmatismo.cloud. |
|
||||
| The licensing of the program under the AGPLv3 does not imply a |
|
||||
| trademark license. Therefore any rights, title and interest in |
|
||||
| our trademarks remain entirely with us. |
|
||||
| |
|
||||
\*****************************************************************************/
|
||||
|
||||
/**
|
||||
* @fileoverview Logging support.
|
||||
*/
|
||||
|
||||
const { createLogger, format, transports } = require('winston');
|
||||
|
||||
const config = {
|
||||
levels: {
|
||||
error: 0,
|
||||
debug: 1,
|
||||
warn: 2,
|
||||
data: 3,
|
||||
info: 4,
|
||||
verbose: 5,
|
||||
silly: 6,
|
||||
custom: 7
|
||||
},
|
||||
colors: {
|
||||
error: 'red',
|
||||
debug: 'blue',
|
||||
warn: 'yellow',
|
||||
data: 'grey',
|
||||
info: 'green',
|
||||
verbose: 'cyan',
|
||||
silly: 'magenta',
|
||||
custom: 'yellow'
|
||||
}
|
||||
};
|
||||
|
||||
const logger = createLogger({
|
||||
format: format.combine(
|
||||
format.colorize(),
|
||||
format.simple(),
|
||||
format.label({ label: 'GB' }),
|
||||
format.timestamp(),
|
||||
format.printf(nfo => {
|
||||
return `${nfo.timestamp.replace(/\-|\.|\d\d\dZ|\:/gi, '' )} ${nfo.label} ${nfo.level} ${nfo.message}`;
|
||||
})
|
||||
),
|
||||
levels: config.levels,
|
||||
transports: [
|
||||
new transports.Console()]
|
||||
});
|
||||
|
||||
const logger2 = createLogger({
|
||||
levels: config.levels,
|
||||
transports: [new (transports.File)({
|
||||
filename: 'GB.log.json', json: true
|
||||
})]
|
||||
});
|
||||
|
||||
module.exports = [logger, logger2];
|
||||
86
src/message_types.rs
Normal file
86
src/message_types.rs
Normal file
|
|
@ -0,0 +1,86 @@
|
|||
//! Message type definitions
|
||||
//!
|
||||
//! Defines the different types of messages in the bot system.
|
||||
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
/// Enum representing different types of messages in the bot system
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
|
||||
#[serde(transparent)]
|
||||
pub struct MessageType(pub i32);
|
||||
|
||||
impl MessageType {
|
||||
/// Regular message from external systems (WhatsApp, Instagram, etc.)
|
||||
pub const EXTERNAL: MessageType = MessageType(0);
|
||||
|
||||
/// User message from web interface
|
||||
pub const USER: MessageType = MessageType(1);
|
||||
|
||||
/// Bot response (can be regular content or event)
|
||||
pub const BOT_RESPONSE: MessageType = MessageType(2);
|
||||
|
||||
/// Continue interrupted response
|
||||
pub const CONTINUE: MessageType = MessageType(3);
|
||||
|
||||
/// Suggestion or command message
|
||||
pub const SUGGESTION: MessageType = MessageType(4);
|
||||
|
||||
/// Context change notification
|
||||
pub const CONTEXT_CHANGE: MessageType = MessageType(5);
|
||||
}
|
||||
|
||||
impl From<i32> for MessageType {
|
||||
fn from(value: i32) -> Self {
|
||||
MessageType(value)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<MessageType> for i32 {
|
||||
fn from(value: MessageType) -> Self {
|
||||
value.0
|
||||
}
|
||||
}
|
||||
|
||||
impl Default for MessageType {
|
||||
fn default() -> Self {
|
||||
MessageType::USER
|
||||
}
|
||||
}
|
||||
|
||||
impl std::fmt::Display for MessageType {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
let name = match self.0 {
|
||||
0 => "EXTERNAL",
|
||||
1 => "USER",
|
||||
2 => "BOT_RESPONSE",
|
||||
3 => "CONTINUE",
|
||||
4 => "SUGGESTION",
|
||||
5 => "CONTEXT_CHANGE",
|
||||
_ => "UNKNOWN",
|
||||
};
|
||||
write!(f, "{}", name)
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn test_message_type_conversion() {
|
||||
assert_eq!(i32::from(MessageType::USER), 1);
|
||||
assert_eq!(MessageType::from(2), MessageType::BOT_RESPONSE);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_message_type_display() {
|
||||
assert_eq!(MessageType::USER.to_string(), "USER");
|
||||
assert_eq!(MessageType::BOT_RESPONSE.to_string(), "BOT_RESPONSE");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_message_type_equality() {
|
||||
assert_eq!(MessageType::USER, MessageType(1));
|
||||
assert_ne!(MessageType::USER, MessageType::BOT_RESPONSE);
|
||||
}
|
||||
}
|
||||
295
src/models.rs
Normal file
295
src/models.rs
Normal file
|
|
@ -0,0 +1,295 @@
|
|||
//! Common models shared across bot ecosystem
|
||||
//!
|
||||
//! Contains DTOs, API response types, and common structures.
|
||||
|
||||
use crate::message_types::MessageType;
|
||||
use chrono::{DateTime, Utc};
|
||||
use serde::{Deserialize, Serialize};
|
||||
use uuid::Uuid;
|
||||
|
||||
/// Standard API response wrapper
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
pub struct ApiResponse<T> {
|
||||
pub success: bool,
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub data: Option<T>,
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub error: Option<String>,
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub message: Option<String>,
|
||||
}
|
||||
|
||||
impl<T> ApiResponse<T> {
|
||||
/// Create a success response with data
|
||||
pub fn success(data: T) -> Self {
|
||||
Self {
|
||||
success: true,
|
||||
data: Some(data),
|
||||
error: None,
|
||||
message: None,
|
||||
}
|
||||
}
|
||||
|
||||
/// Create a success response with message
|
||||
pub fn success_message(data: T, message: impl Into<String>) -> Self {
|
||||
Self {
|
||||
success: true,
|
||||
data: Some(data),
|
||||
error: None,
|
||||
message: Some(message.into()),
|
||||
}
|
||||
}
|
||||
|
||||
/// Create an error response
|
||||
pub fn error(message: impl Into<String>) -> Self {
|
||||
Self {
|
||||
success: false,
|
||||
data: None,
|
||||
error: Some(message.into()),
|
||||
message: None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: Default> Default for ApiResponse<T> {
|
||||
fn default() -> Self {
|
||||
Self::success(T::default())
|
||||
}
|
||||
}
|
||||
|
||||
/// User session information
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
pub struct Session {
|
||||
pub id: Uuid,
|
||||
pub user_id: Uuid,
|
||||
pub bot_id: Uuid,
|
||||
pub title: String,
|
||||
pub created_at: DateTime<Utc>,
|
||||
pub updated_at: DateTime<Utc>,
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub expires_at: Option<DateTime<Utc>>,
|
||||
}
|
||||
|
||||
impl Session {
|
||||
/// Check if session is expired
|
||||
pub fn is_expired(&self) -> bool {
|
||||
if let Some(expires) = self.expires_at {
|
||||
Utc::now() > expires
|
||||
} else {
|
||||
false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// User message sent to bot
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
pub struct UserMessage {
|
||||
pub bot_id: String,
|
||||
pub user_id: String,
|
||||
pub session_id: String,
|
||||
pub channel: String,
|
||||
pub content: String,
|
||||
pub message_type: MessageType,
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub media_url: Option<String>,
|
||||
pub timestamp: DateTime<Utc>,
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub context_name: Option<String>,
|
||||
}
|
||||
|
||||
impl UserMessage {
|
||||
/// Create a new text message
|
||||
pub fn text(
|
||||
bot_id: impl Into<String>,
|
||||
user_id: impl Into<String>,
|
||||
session_id: impl Into<String>,
|
||||
channel: impl Into<String>,
|
||||
content: impl Into<String>,
|
||||
) -> Self {
|
||||
Self {
|
||||
bot_id: bot_id.into(),
|
||||
user_id: user_id.into(),
|
||||
session_id: session_id.into(),
|
||||
channel: channel.into(),
|
||||
content: content.into(),
|
||||
message_type: MessageType::USER,
|
||||
media_url: None,
|
||||
timestamp: Utc::now(),
|
||||
context_name: None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Suggestion for user
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
pub struct Suggestion {
|
||||
pub text: String,
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub context: Option<String>,
|
||||
}
|
||||
|
||||
impl Suggestion {
|
||||
pub fn new(text: impl Into<String>) -> Self {
|
||||
Self {
|
||||
text: text.into(),
|
||||
context: None,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn with_context(text: impl Into<String>, context: impl Into<String>) -> Self {
|
||||
Self {
|
||||
text: text.into(),
|
||||
context: Some(context.into()),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Bot response to user
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
pub struct BotResponse {
|
||||
pub bot_id: String,
|
||||
pub user_id: String,
|
||||
pub session_id: String,
|
||||
pub channel: String,
|
||||
pub content: String,
|
||||
pub message_type: MessageType,
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub stream_token: Option<String>,
|
||||
pub is_complete: bool,
|
||||
#[serde(default)]
|
||||
pub suggestions: Vec<Suggestion>,
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub context_name: Option<String>,
|
||||
#[serde(default)]
|
||||
pub context_length: usize,
|
||||
#[serde(default)]
|
||||
pub context_max_length: usize,
|
||||
}
|
||||
|
||||
impl BotResponse {
|
||||
/// Create a new bot response
|
||||
pub fn new(
|
||||
bot_id: impl Into<String>,
|
||||
session_id: impl Into<String>,
|
||||
user_id: impl Into<String>,
|
||||
content: impl Into<String>,
|
||||
channel: impl Into<String>,
|
||||
) -> Self {
|
||||
Self {
|
||||
bot_id: bot_id.into(),
|
||||
user_id: user_id.into(),
|
||||
session_id: session_id.into(),
|
||||
channel: channel.into(),
|
||||
content: content.into(),
|
||||
message_type: MessageType::BOT_RESPONSE,
|
||||
stream_token: None,
|
||||
is_complete: true,
|
||||
suggestions: Vec::new(),
|
||||
context_name: None,
|
||||
context_length: 0,
|
||||
context_max_length: 0,
|
||||
}
|
||||
}
|
||||
|
||||
/// Create a streaming response
|
||||
pub fn streaming(
|
||||
bot_id: impl Into<String>,
|
||||
session_id: impl Into<String>,
|
||||
user_id: impl Into<String>,
|
||||
channel: impl Into<String>,
|
||||
stream_token: impl Into<String>,
|
||||
) -> Self {
|
||||
Self {
|
||||
bot_id: bot_id.into(),
|
||||
user_id: user_id.into(),
|
||||
session_id: session_id.into(),
|
||||
channel: channel.into(),
|
||||
content: String::new(),
|
||||
message_type: MessageType::BOT_RESPONSE,
|
||||
stream_token: Some(stream_token.into()),
|
||||
is_complete: false,
|
||||
suggestions: Vec::new(),
|
||||
context_name: None,
|
||||
context_length: 0,
|
||||
context_max_length: 0,
|
||||
}
|
||||
}
|
||||
|
||||
/// Add suggestions to response
|
||||
pub fn with_suggestions(mut self, suggestions: Vec<Suggestion>) -> Self {
|
||||
self.suggestions = suggestions;
|
||||
self
|
||||
}
|
||||
}
|
||||
|
||||
impl Default for BotResponse {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
bot_id: String::new(),
|
||||
user_id: String::new(),
|
||||
session_id: String::new(),
|
||||
channel: String::new(),
|
||||
content: String::new(),
|
||||
message_type: MessageType::BOT_RESPONSE,
|
||||
stream_token: None,
|
||||
is_complete: true,
|
||||
suggestions: Vec::new(),
|
||||
context_name: None,
|
||||
context_length: 0,
|
||||
context_max_length: 0,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Attachment for media files in messages
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
pub struct Attachment {
|
||||
/// Type of attachment (image, audio, video, file, etc.)
|
||||
pub attachment_type: String,
|
||||
/// URL or path to the attachment
|
||||
pub url: String,
|
||||
/// MIME type of the attachment
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub mime_type: Option<String>,
|
||||
/// File name if available
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub filename: Option<String>,
|
||||
/// File size in bytes
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub size: Option<u64>,
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn test_api_response_success() {
|
||||
let response: ApiResponse<String> = ApiResponse::success("test".to_string());
|
||||
assert!(response.success);
|
||||
assert_eq!(response.data, Some("test".to_string()));
|
||||
assert!(response.error.is_none());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_api_response_error() {
|
||||
let response: ApiResponse<String> = ApiResponse::error("something went wrong");
|
||||
assert!(!response.success);
|
||||
assert!(response.data.is_none());
|
||||
assert_eq!(response.error, Some("something went wrong".to_string()));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_user_message_creation() {
|
||||
let msg = UserMessage::text("bot1", "user1", "sess1", "web", "Hello!");
|
||||
assert_eq!(msg.content, "Hello!");
|
||||
assert_eq!(msg.message_type, MessageType::USER);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_bot_response_creation() {
|
||||
let response = BotResponse::new("bot1", "sess1", "user1", "Hi there!", "web");
|
||||
assert!(response.is_complete);
|
||||
assert_eq!(response.message_type, MessageType::BOT_RESPONSE);
|
||||
}
|
||||
}
|
||||
348
src/version.rs
Normal file
348
src/version.rs
Normal file
|
|
@ -0,0 +1,348 @@
|
|||
//! Version Tracking Module
|
||||
//!
|
||||
//! Tracks versions of all components and checks for updates.
|
||||
|
||||
use chrono::{DateTime, Utc};
|
||||
use log::debug;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use std::collections::HashMap;
|
||||
use std::sync::RwLock;
|
||||
|
||||
/// Global version registry
|
||||
static VERSION_REGISTRY: RwLock<Option<VersionRegistry>> = RwLock::new(None);
|
||||
|
||||
/// Current botserver version from Cargo.toml
|
||||
pub const BOTSERVER_VERSION: &str = env!("CARGO_PKG_VERSION");
|
||||
pub const BOTSERVER_NAME: &str = env!("CARGO_PKG_NAME");
|
||||
|
||||
/// Component version information
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
pub struct ComponentVersion {
|
||||
/// Component name
|
||||
pub name: String,
|
||||
/// Current installed version
|
||||
pub version: String,
|
||||
/// Latest available version (if known)
|
||||
pub latest_version: Option<String>,
|
||||
/// Whether an update is available
|
||||
pub update_available: bool,
|
||||
/// Component status
|
||||
pub status: ComponentStatus,
|
||||
/// Last check time
|
||||
pub last_checked: Option<DateTime<Utc>>,
|
||||
/// Source/origin of the component
|
||||
pub source: ComponentSource,
|
||||
/// Additional metadata
|
||||
pub metadata: HashMap<String, String>,
|
||||
}
|
||||
|
||||
/// Component status
|
||||
#[derive(Debug, Clone, Copy, Serialize, Deserialize, PartialEq, Eq)]
|
||||
pub enum ComponentStatus {
|
||||
Running,
|
||||
Stopped,
|
||||
Error,
|
||||
Updating,
|
||||
NotInstalled,
|
||||
Unknown,
|
||||
}
|
||||
|
||||
impl std::fmt::Display for ComponentStatus {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
match self {
|
||||
ComponentStatus::Running => write!(f, "[OK] Running"),
|
||||
ComponentStatus::Stopped => write!(f, "[STOP] Stopped"),
|
||||
ComponentStatus::Error => write!(f, "[ERR] Error"),
|
||||
ComponentStatus::Updating => write!(f, "[UPD] Updating"),
|
||||
ComponentStatus::NotInstalled => write!(f, "[--] Not Installed"),
|
||||
ComponentStatus::Unknown => write!(f, "[?] Unknown"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Component source type
|
||||
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
|
||||
pub enum ComponentSource {
|
||||
Builtin,
|
||||
Docker,
|
||||
Lxc,
|
||||
System,
|
||||
Binary,
|
||||
External,
|
||||
}
|
||||
|
||||
impl std::fmt::Display for ComponentSource {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
match self {
|
||||
ComponentSource::Builtin => write!(f, "Built-in"),
|
||||
ComponentSource::Docker => write!(f, "Docker"),
|
||||
ComponentSource::Lxc => write!(f, "LXC"),
|
||||
ComponentSource::System => write!(f, "System"),
|
||||
ComponentSource::Binary => write!(f, "Binary"),
|
||||
ComponentSource::External => write!(f, "External"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Version registry holding all component versions
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
pub struct VersionRegistry {
|
||||
pub core_version: String,
|
||||
pub components: HashMap<String, ComponentVersion>,
|
||||
pub last_update_check: Option<DateTime<Utc>>,
|
||||
pub update_url: Option<String>,
|
||||
}
|
||||
|
||||
impl Default for VersionRegistry {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
core_version: BOTSERVER_VERSION.to_string(),
|
||||
components: HashMap::new(),
|
||||
last_update_check: None,
|
||||
update_url: Some("https://api.generalbots.com/updates".to_string()),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl VersionRegistry {
|
||||
/// Create a new version registry
|
||||
pub fn new() -> Self {
|
||||
let mut registry = Self::default();
|
||||
registry.register_builtin_components();
|
||||
registry
|
||||
}
|
||||
|
||||
/// Register built-in components
|
||||
fn register_builtin_components(&mut self) {
|
||||
self.register_component(ComponentVersion {
|
||||
name: "botserver".to_string(),
|
||||
version: BOTSERVER_VERSION.to_string(),
|
||||
latest_version: None,
|
||||
update_available: false,
|
||||
status: ComponentStatus::Running,
|
||||
last_checked: Some(Utc::now()),
|
||||
source: ComponentSource::Builtin,
|
||||
metadata: HashMap::from([
|
||||
("description".to_string(), "Core bot server".to_string()),
|
||||
(
|
||||
"repo".to_string(),
|
||||
"https://github.com/GeneralBots/botserver".to_string(),
|
||||
),
|
||||
]),
|
||||
});
|
||||
|
||||
self.register_component(ComponentVersion {
|
||||
name: "basic".to_string(),
|
||||
version: BOTSERVER_VERSION.to_string(),
|
||||
latest_version: None,
|
||||
update_available: false,
|
||||
status: ComponentStatus::Running,
|
||||
last_checked: Some(Utc::now()),
|
||||
source: ComponentSource::Builtin,
|
||||
metadata: HashMap::from([(
|
||||
"description".to_string(),
|
||||
"BASIC script interpreter".to_string(),
|
||||
)]),
|
||||
});
|
||||
|
||||
self.register_component(ComponentVersion {
|
||||
name: "llm".to_string(),
|
||||
version: BOTSERVER_VERSION.to_string(),
|
||||
latest_version: None,
|
||||
update_available: false,
|
||||
status: ComponentStatus::Running,
|
||||
last_checked: Some(Utc::now()),
|
||||
source: ComponentSource::Builtin,
|
||||
metadata: HashMap::from([(
|
||||
"description".to_string(),
|
||||
"LLM integration (Claude, GPT, etc.)".to_string(),
|
||||
)]),
|
||||
});
|
||||
}
|
||||
|
||||
/// Register a component
|
||||
pub fn register_component(&mut self, component: ComponentVersion) {
|
||||
debug!(
|
||||
"Registered component: {} v{}",
|
||||
component.name, component.version
|
||||
);
|
||||
self.components.insert(component.name.clone(), component);
|
||||
}
|
||||
|
||||
/// Update component status
|
||||
pub fn update_status(&mut self, name: &str, status: ComponentStatus) {
|
||||
if let Some(component) = self.components.get_mut(name) {
|
||||
component.status = status;
|
||||
}
|
||||
}
|
||||
|
||||
/// Update component version
|
||||
pub fn update_version(&mut self, name: &str, version: String) {
|
||||
if let Some(component) = self.components.get_mut(name) {
|
||||
component.version = version;
|
||||
component.last_checked = Some(Utc::now());
|
||||
}
|
||||
}
|
||||
|
||||
/// Get component by name
|
||||
pub fn get_component(&self, name: &str) -> Option<&ComponentVersion> {
|
||||
self.components.get(name)
|
||||
}
|
||||
|
||||
/// Get all components
|
||||
pub fn get_all_components(&self) -> &HashMap<String, ComponentVersion> {
|
||||
&self.components
|
||||
}
|
||||
|
||||
/// Get components with available updates
|
||||
pub fn get_available_updates(&self) -> Vec<&ComponentVersion> {
|
||||
self.components
|
||||
.values()
|
||||
.filter(|c| c.update_available)
|
||||
.collect()
|
||||
}
|
||||
|
||||
/// Get summary of all components
|
||||
pub fn summary(&self) -> String {
|
||||
let running = self
|
||||
.components
|
||||
.values()
|
||||
.filter(|c| c.status == ComponentStatus::Running)
|
||||
.count();
|
||||
let total = self.components.len();
|
||||
let updates = self.get_available_updates().len();
|
||||
|
||||
format!(
|
||||
"{} v{} | {}/{} components running | {} updates available",
|
||||
BOTSERVER_NAME, self.core_version, running, total, updates
|
||||
)
|
||||
}
|
||||
|
||||
/// Get summary as JSON
|
||||
pub fn to_json(&self) -> Result<String, serde_json::Error> {
|
||||
serde_json::to_string_pretty(self)
|
||||
}
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
// Global Access Functions
|
||||
// ============================================================================
|
||||
|
||||
/// Initialize version registry at startup
|
||||
pub fn init_version_registry() {
|
||||
let registry = VersionRegistry::new();
|
||||
if let Ok(mut guard) = VERSION_REGISTRY.write() {
|
||||
*guard = Some(registry);
|
||||
}
|
||||
}
|
||||
|
||||
/// Get version registry (read-only)
|
||||
pub fn version_registry() -> Option<VersionRegistry> {
|
||||
VERSION_REGISTRY.read().ok()?.clone()
|
||||
}
|
||||
|
||||
/// Get mutable version registry
|
||||
pub fn version_registry_mut(
|
||||
) -> Option<std::sync::RwLockWriteGuard<'static, Option<VersionRegistry>>> {
|
||||
VERSION_REGISTRY.write().ok()
|
||||
}
|
||||
|
||||
/// Register a component
|
||||
pub fn register_component(component: ComponentVersion) {
|
||||
if let Ok(mut guard) = VERSION_REGISTRY.write() {
|
||||
if let Some(ref mut registry) = *guard {
|
||||
registry.register_component(component);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Update component status
|
||||
pub fn update_component_status(name: &str, status: ComponentStatus) {
|
||||
if let Ok(mut guard) = VERSION_REGISTRY.write() {
|
||||
if let Some(ref mut registry) = *guard {
|
||||
registry.update_status(name, status);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Get component version
|
||||
pub fn get_component_version(name: &str) -> Option<ComponentVersion> {
|
||||
VERSION_REGISTRY
|
||||
.read()
|
||||
.ok()?
|
||||
.as_ref()?
|
||||
.get_component(name)
|
||||
.cloned()
|
||||
}
|
||||
|
||||
/// Get botserver version
|
||||
pub fn get_botserver_version() -> &'static str {
|
||||
BOTSERVER_VERSION
|
||||
}
|
||||
|
||||
/// Get version string for display
|
||||
pub fn version_string() -> String {
|
||||
format!("{} v{}", BOTSERVER_NAME, BOTSERVER_VERSION)
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn test_registry_creation() {
|
||||
let registry = VersionRegistry::new();
|
||||
assert!(!registry.core_version.is_empty());
|
||||
assert!(registry.components.contains_key("botserver"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_component_registration() {
|
||||
let mut registry = VersionRegistry::new();
|
||||
registry.register_component(ComponentVersion {
|
||||
name: "test".to_string(),
|
||||
version: "1.0.0".to_string(),
|
||||
latest_version: None,
|
||||
update_available: false,
|
||||
status: ComponentStatus::Running,
|
||||
last_checked: None,
|
||||
source: ComponentSource::Builtin,
|
||||
metadata: HashMap::new(),
|
||||
});
|
||||
assert!(registry.get_component("test").is_some());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_status_display() {
|
||||
assert_eq!(ComponentStatus::Running.to_string(), "[OK] Running");
|
||||
assert_eq!(ComponentStatus::Error.to_string(), "[ERR] Error");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_version_string() {
|
||||
let vs = version_string();
|
||||
assert!(!vs.is_empty());
|
||||
assert!(vs.contains('v'));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_source_display() {
|
||||
assert_eq!(ComponentSource::Builtin.to_string(), "Built-in");
|
||||
assert_eq!(ComponentSource::Docker.to_string(), "Docker");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_update_status() {
|
||||
let mut registry = VersionRegistry::new();
|
||||
registry.update_status("botserver", ComponentStatus::Stopped);
|
||||
let component = registry.get_component("botserver").unwrap();
|
||||
assert_eq!(component.status, ComponentStatus::Stopped);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_summary() {
|
||||
let registry = VersionRegistry::new();
|
||||
let summary = registry.summary();
|
||||
assert!(summary.contains("components running"));
|
||||
}
|
||||
}
|
||||
|
|
@ -1,32 +0,0 @@
|
|||
{
|
||||
"compilerOptions": {
|
||||
"allowJs": false,
|
||||
"baseUrl": "./",
|
||||
"declaration": true,
|
||||
"emitDecoratorMetadata": true,
|
||||
"experimentalDecorators": true,
|
||||
"skipLibCheck": true,
|
||||
"mapRoot": "./dist/",
|
||||
"module": "commonjs",
|
||||
"moduleResolution": "node",
|
||||
"outDir": "./dist",
|
||||
"paths": {
|
||||
"pragmatismo-io-framework/*": [
|
||||
"node_modules/pragmatismo-io-framework/*"
|
||||
]
|
||||
},
|
||||
"sourceMap": true,
|
||||
"target": "es6",
|
||||
"typeRoots": [
|
||||
"node_modules/@types"
|
||||
]
|
||||
},
|
||||
"include": [
|
||||
"test/**/*",
|
||||
"src/**/*"
|
||||
],
|
||||
"exclude": [
|
||||
"dist",
|
||||
"node_modules"
|
||||
]
|
||||
}
|
||||
16
typedoc.json
16
typedoc.json
|
|
@ -1,16 +0,0 @@
|
|||
{
|
||||
"mode": "modules",
|
||||
"out": "docs",
|
||||
"name": "General Bots® Open Core",
|
||||
"theme": "default",
|
||||
"ignoreCompilerErrors": "true",
|
||||
"experimentalDecorators": "true",
|
||||
"emitDecoratorMetadata": "true",
|
||||
"target": "ES6",
|
||||
"moduleResolution": "node",
|
||||
"preserveConstEnums": "true",
|
||||
"stripInternal": "true",
|
||||
"suppressExcessPropertyErrors": "true",
|
||||
"suppressImplicitAnyIndexErrors": "true",
|
||||
"module": "commonjs"
|
||||
}
|
||||
Loading…
Add table
Reference in a new issue