mirror of
https://github.com/bitcoinresearchkit/brk.git
synced 2026-06-14 08:43:35 -07:00
website: add screenshot feature
This commit is contained in:
Generated
+11
-8
@@ -1735,9 +1735,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "fancy-regex"
|
||||
version = "0.14.0"
|
||||
version = "0.16.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6e24cb5a94bcae1e5408b0effca5cd7172ea3c5755049c5f3af4cd283a165298"
|
||||
checksum = "bf04c5ec15464ace8355a7b440a33aece288993475556d461154d7a62ad9947c"
|
||||
dependencies = [
|
||||
"bit-set",
|
||||
"regex-automata",
|
||||
@@ -3054,9 +3054,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "oxc_resolver"
|
||||
version = "11.6.2"
|
||||
version = "11.7.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3d84cdcd778d15db5b21cc61baf79ac55cee97e7feb725b2664453979ba3cd76"
|
||||
checksum = "0784392356fa78dd4c9047fce7c9046c141f8990736792d00310bf40935b1870"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"indexmap 2.11.0",
|
||||
@@ -3407,9 +3407,9 @@ checksum = "7edddbd0b52d732b21ad9a5fab5c704c14cd949e5e9a1ec5929a24fded1b904c"
|
||||
|
||||
[[package]]
|
||||
name = "pnp"
|
||||
version = "0.12.1"
|
||||
version = "0.12.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ab3167cbab15e437e9c7db8a4cf613eb4a77583d4327a8964d50fedd6cf364bd"
|
||||
checksum = "e001eb06e9523653f2a88adb94e286ef5d7acfe64158b21bf57a6f6bc3ba65ca"
|
||||
dependencies = [
|
||||
"byteorder",
|
||||
"clean-path",
|
||||
@@ -3602,9 +3602,12 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "rapidhash"
|
||||
version = "3.1.0"
|
||||
version = "4.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "efee4b7317469c6c6e7fdeee3d094313af846a97678d6ed971d83a852d730083"
|
||||
checksum = "9d126f24bc587b080d7823a831d0fe832090a606fd3fd244ecbe23c561104ab8"
|
||||
dependencies = [
|
||||
"rustversion",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rayon"
|
||||
|
||||
@@ -10,30 +10,19 @@
|
||||
- pull latest version and notify is out of date
|
||||
- _computer_
|
||||
- **add rollback of states (in stateful)**
|
||||
- remove configurable format (raw/compressed) and chose sane ones instead
|
||||
- linear reads: compressed (height/date/... + txindex_to_height + txindex_to_version + ...)
|
||||
- random reads: raw (outputindex_to_value + ...)
|
||||
- add costs basis by percentile (percentile cost basis) back
|
||||
- add support for per index computation
|
||||
- fix min feerate which is always ZERO due to coinbase transaction
|
||||
- before computing multiple sources check their length, panic if not equal
|
||||
- add oracle price dataset (https://utxo.live/oracle/UTXOracle.py)
|
||||
- add address counts relative to all datasets
|
||||
- make decade, quarter, year datasets `computed` instead of `eager`
|
||||
- add 6 months (semester) interval datasets to builder
|
||||
- some datasets in `indexes` can probably be removed
|
||||
- add revived/sent supply datasets
|
||||
- add `in-sats` version of all price datasets (average and co)
|
||||
- add `p2pk` group (sum of `p2pk33` and `p2pk65`)
|
||||
- add chopiness datasets
|
||||
- add utxo count, address count, supply data for by reused addresses in groups by address type
|
||||
- add more date ranges (3-6 months and more)
|
||||
- add puell multiple dataset
|
||||
- add pi cycle dataset
|
||||
- add emas of price
|
||||
- add 7d and 30d ema to sell side risk ratio and sopr
|
||||
- don't compute everything for all cohorts as some datasets combinations are irrelevant
|
||||
- addresses/utxos by amount don't need mvrvz for example
|
||||
- add all possible charts from:
|
||||
- https://mainnet.observer
|
||||
- https://glassnode.com
|
||||
|
||||
@@ -17,7 +17,7 @@ vecdb = {workspace = true}
|
||||
byteview = { workspace = true }
|
||||
derive_deref = { workspace = true }
|
||||
jiff = { workspace = true }
|
||||
rapidhash = "3.1.0"
|
||||
rapidhash = "4.0.0"
|
||||
serde = { workspace = true }
|
||||
serde_bytes = { workspace = true }
|
||||
zerocopy = { workspace = true }
|
||||
|
||||
@@ -556,6 +556,10 @@
|
||||
&:has(input:checked) {
|
||||
color: var(--color);
|
||||
}
|
||||
|
||||
[data-screenshot="true"] &:has(input:not(:checked)) {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
main {
|
||||
@@ -971,7 +975,6 @@
|
||||
flex-shrink: 0;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 1.5rem;
|
||||
margin: -0.5rem var(--negative-main-padding);
|
||||
padding: 0.75rem var(--main-padding);
|
||||
overflow-x: auto;
|
||||
@@ -989,13 +992,33 @@
|
||||
margin-top: 2rem;
|
||||
margin-bottom: 1rem;
|
||||
|
||||
button#screenshot {
|
||||
width: 100%;
|
||||
text-align: left;
|
||||
padding-left: 1rem;
|
||||
height: 100%;
|
||||
font-size: var(--font-size-sm);
|
||||
line-height: var(--line-height-sm);
|
||||
|
||||
[data-screenshot="true"] & {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
> legend {
|
||||
gap: 1.5rem;
|
||||
|
||||
&:empty {
|
||||
display: none;
|
||||
}
|
||||
|
||||
> div {
|
||||
[data-screenshot="true"] &:has(input:not(:checked)) {
|
||||
display: none;
|
||||
}
|
||||
|
||||
flex: 0;
|
||||
height: 100%;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
@@ -1033,6 +1056,11 @@
|
||||
padding-right: 0.375rem;
|
||||
margin-left: -0.375rem;
|
||||
margin-right: -0.375rem;
|
||||
|
||||
[data-screenshot="true"] & {
|
||||
width: 0;
|
||||
opacity: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1118,6 +1146,16 @@
|
||||
width: 100%;
|
||||
min-height: 0;
|
||||
padding: var(--main-padding);
|
||||
background-color: var(--background-color);
|
||||
|
||||
p#domain {
|
||||
position: absolute;
|
||||
left: 2rem;
|
||||
top: 0.75rem;
|
||||
color: var(--gray);
|
||||
font-size: var(--font-size-sm);
|
||||
line-height: var(--line-height-sm);
|
||||
}
|
||||
|
||||
header {
|
||||
flex-shrink: 0;
|
||||
@@ -1141,6 +1179,17 @@
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
#interval {
|
||||
> span {
|
||||
display: none;
|
||||
|
||||
[data-screenshot="true"] & {
|
||||
color: var(--gray);
|
||||
display: inline-block;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
> .chart > legend,
|
||||
> fieldset {
|
||||
z-index: 20;
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
LICENSE
|
||||
*.json
|
||||
*webcomponent*
|
||||
README.md
|
||||
README*.md
|
||||
cli*
|
||||
extras/
|
||||
*.cjs
|
||||
@@ -9,3 +9,7 @@ dev.js
|
||||
*.development*
|
||||
*.iife.*
|
||||
nano.*
|
||||
worker.*
|
||||
*.ts
|
||||
*.mts
|
||||
*.cts
|
||||
|
||||
@@ -1,215 +0,0 @@
|
||||
declare class uFuzzy {
|
||||
constructor(opts?: uFuzzy.Options);
|
||||
|
||||
/** search API composed of filter/info/sort, with a info/ranking threshold (1e3) and fast outOfOrder impl */
|
||||
search(
|
||||
haystack: string[],
|
||||
needle: string,
|
||||
/** limit how many terms will be permuted, default = 0; 5 will result in up to 5! (120) search iterations. be careful with this! */
|
||||
outOfOrder?: number,
|
||||
/** default = 1e3 */
|
||||
infoThresh?: number,
|
||||
preFiltered?: uFuzzy.HaystackIdxs | null,
|
||||
): uFuzzy.SearchResult;
|
||||
|
||||
/** initial haystack filter, can accept idxs from previous prefix/typeahead match as optimization */
|
||||
filter(
|
||||
haystack: string[],
|
||||
needle: string,
|
||||
idxs?: uFuzzy.HaystackIdxs,
|
||||
): uFuzzy.HaystackIdxs | null;
|
||||
|
||||
/** collects stats about pre-filtered matches, does additional filtering based on term boundary settings, finds highlight ranges */
|
||||
info(
|
||||
idxs: uFuzzy.HaystackIdxs,
|
||||
haystack: string[],
|
||||
needle: string,
|
||||
): uFuzzy.Info;
|
||||
|
||||
/** performs final result sorting via Array.sort(), relying on Info */
|
||||
sort(
|
||||
info: uFuzzy.Info,
|
||||
haystack: string[],
|
||||
needle: string,
|
||||
): uFuzzy.InfoIdxOrder;
|
||||
|
||||
/** utility for splitting needle into terms following defined interSplit/intraSplit opts. useful for out-of-order permutes */
|
||||
split(needle: string, keepCase?: boolean): uFuzzy.Terms;
|
||||
|
||||
/** util for creating out-of-order permutations of a needle terms array */
|
||||
static permute(arr: unknown[]): unknown[][];
|
||||
|
||||
/** util for replacing common diacritics/accents */
|
||||
static latinize<T extends string[] | string>(strings: T): T;
|
||||
|
||||
/** util for highlighting matched substr parts of a result */
|
||||
static highlight<TAccum = string, TMarkedPart = string>(
|
||||
match: string,
|
||||
ranges: number[],
|
||||
|
||||
mark?: (part: string, matched: boolean) => TMarkedPart,
|
||||
accum?: TAccum,
|
||||
append?: (accum: TAccum, part: TMarkedPart) => TAccum | undefined,
|
||||
): TAccum;
|
||||
}
|
||||
|
||||
export = uFuzzy;
|
||||
|
||||
declare namespace uFuzzy {
|
||||
/** needle's terms */
|
||||
export type Terms = string[];
|
||||
|
||||
/** subset of idxs of a haystack array */
|
||||
export type HaystackIdxs = number[];
|
||||
|
||||
/** sorted order in which info facets should be iterated */
|
||||
export type InfoIdxOrder = number[];
|
||||
|
||||
export type AbortedResult = [null, null, null];
|
||||
|
||||
export type FilteredResult = [uFuzzy.HaystackIdxs, null, null];
|
||||
|
||||
export type RankedResult = [
|
||||
uFuzzy.HaystackIdxs,
|
||||
uFuzzy.Info,
|
||||
uFuzzy.InfoIdxOrder,
|
||||
];
|
||||
|
||||
export type SearchResult = FilteredResult | RankedResult | AbortedResult;
|
||||
|
||||
/** partial RegExp */
|
||||
type PartialRegExp = string;
|
||||
|
||||
/** what should be considered acceptable term bounds */
|
||||
export const enum BoundMode {
|
||||
/** will match 'man' substr anywhere. e.g. tasmania */
|
||||
Any = 0,
|
||||
/** will match 'man' at whitespace, punct, case-change, and alpha-num boundaries. e.g. mantis, SuperMan, fooManBar, 0007man */
|
||||
Loose = 1,
|
||||
/** will match 'man' at whitespace, punct boundaries only. e.g. mega man, walk_man, man-made, foo.man.bar */
|
||||
Strict = 2,
|
||||
}
|
||||
|
||||
export const enum IntraMode {
|
||||
/** allows any number of extra char insertions within a term, but all term chars must be present for a match */
|
||||
MultiInsert = 0,
|
||||
/** allows for a single-char substitution, transposition, insertion, or deletion within terms (excluding first and last chars) */
|
||||
SingleError = 1,
|
||||
}
|
||||
|
||||
export type IntraSliceIdxs = [from: number, to: number];
|
||||
|
||||
type CompareFn = (a: string, b: string) => number;
|
||||
|
||||
export interface Options {
|
||||
// whether regexps use a /u unicode flag
|
||||
unicode?: boolean; // false
|
||||
|
||||
/** @deprecated renamed to opts.alpha */
|
||||
letters?: PartialRegExp | null; // a-z
|
||||
|
||||
// regexp character class [] of chars which should be treated as letters (case insensitive)
|
||||
alpha?: PartialRegExp | null; // a-z
|
||||
|
||||
/** term segmentation & punct/whitespace merging */
|
||||
interSplit?: PartialRegExp; // '[^A-Za-z\\d']+'
|
||||
intraSplit?: PartialRegExp | null; // '[a-z][A-Z]'
|
||||
|
||||
/** inter bounds that will be used to increase lft2/rgt2 info counters */
|
||||
interBound?: PartialRegExp | null; // '[^A-Za-z\\d]'
|
||||
/** intra bounds that will be used to increase lft1/rgt1 info counters */
|
||||
intraBound?: PartialRegExp | null; // '[A-Za-z][0-9]|[0-9][A-Za-z]|[a-z][A-Z]'
|
||||
|
||||
/** inter-term modes, during .info() can discard matches when bounds conditions are not met */
|
||||
interLft?: BoundMode; // 0
|
||||
interRgt?: BoundMode; // 0
|
||||
|
||||
/** allowance between terms */
|
||||
interChars?: PartialRegExp; // '.'
|
||||
interIns?: number; // Infinity
|
||||
|
||||
/** allowance between chars within terms */
|
||||
intraChars?: PartialRegExp; // '[a-z\\d]'
|
||||
intraIns?: number; // 0
|
||||
|
||||
/** contractions detection */
|
||||
intraContr?: PartialRegExp; // "'[a-z]{1,2}\\b"
|
||||
|
||||
/** error tolerance mode within terms. will clamp intraIns to 1 when set to SingleError */
|
||||
intraMode?: IntraMode; // 0
|
||||
|
||||
/** which part of each term should tolerate errors (when intraMode: 1) */
|
||||
intraSlice?: IntraSliceIdxs; // [1, Infinity]
|
||||
|
||||
/** max substitutions (when intraMode: 1) */
|
||||
intraSub?: 0 | 1; // 0
|
||||
/** max transpositions (when intraMode: 1) */
|
||||
intraTrn?: 0 | 1; // 0
|
||||
/** max omissions/deletions (when intraMode: 1) */
|
||||
intraDel?: 0 | 1; // 0
|
||||
|
||||
/** can dynamically adjust error tolerance rules per term in needle (when intraMode: 1) */
|
||||
intraRules?: (term: string) => {
|
||||
intraSlice?: IntraSliceIdxs;
|
||||
intraIns: 0 | 1;
|
||||
intraSub: 0 | 1;
|
||||
intraTrn: 0 | 1;
|
||||
intraDel: 0 | 1;
|
||||
};
|
||||
|
||||
/** post-filters matches during .info() based on cmp of term in needle vs partial match */
|
||||
intraFilt?: (term: string, match: string, index: number) => boolean; // should this also accept WIP info?
|
||||
|
||||
/** default: toLocaleUpperCase() */
|
||||
toUpper?: (str: string) => string;
|
||||
|
||||
/** default: toLocaleLowerCase() */
|
||||
toLower?: (str: string) => string;
|
||||
|
||||
/** final sorting cmp when all other match metrics are equal */
|
||||
compare?: CompareFn;
|
||||
|
||||
sort?: (
|
||||
info: Info,
|
||||
haystack: string[],
|
||||
needle: string,
|
||||
compare?: CompareFn,
|
||||
) => InfoIdxOrder;
|
||||
}
|
||||
|
||||
export interface Info {
|
||||
/** matched idxs from haystack */
|
||||
idx: HaystackIdxs;
|
||||
|
||||
/** match offsets */
|
||||
start: number[];
|
||||
|
||||
/** number of left BoundMode.Strict term boundaries found */
|
||||
interLft2: number[];
|
||||
/** number of right BoundMode.Strict term boundaries found */
|
||||
interRgt2: number[];
|
||||
/** number of left BoundMode.Loose term boundaries found */
|
||||
interLft1: number[];
|
||||
/** number of right BoundMode.Loose term boundaries found */
|
||||
interRgt1: number[];
|
||||
|
||||
/** total number of extra chars matched within all terms. higher = matched terms have more fuzz in them */
|
||||
intraIns: number[];
|
||||
/** total number of chars found in between matched terms. higher = terms are more sparse, have more fuzz in between them */
|
||||
interIns: number[];
|
||||
|
||||
/** total number of matched contiguous chars (substrs but not necessarily full terms) */
|
||||
chars: number[];
|
||||
|
||||
/** number of exactly-matched terms (intra = 0) where both lft and rgt landed on a BoundMode.Loose or BoundMode.Strict boundary */
|
||||
terms: number[];
|
||||
|
||||
/** number of needle terms with case-sensitive partial matches */
|
||||
cases: number[];
|
||||
|
||||
/** offset ranges within match for highlighting: [startIdx0, endIdx0, startIdx1, endIdx1,...] */
|
||||
ranges: number[][];
|
||||
}
|
||||
}
|
||||
|
||||
export as namespace uFuzzy;
|
||||
+28
-18
@@ -4,7 +4,7 @@
|
||||
*
|
||||
* uFuzzy.js (μFuzzy)
|
||||
* A tiny, efficient fuzzy matcher that doesn't suck
|
||||
* https://github.com/leeoniya/uFuzzy (v1.0.18)
|
||||
* https://github.com/leeoniya/uFuzzy (v1.0.19)
|
||||
*/
|
||||
|
||||
const cmp = (a, b) => a > b ? 1 : a < b ? -1 : 0;
|
||||
@@ -925,40 +925,50 @@ function uFuzzy(opts) {
|
||||
|
||||
const latinize = (() => {
|
||||
let accents = {
|
||||
A: 'ÁÀÃÂÄĄ',
|
||||
a: 'áàãâäą',
|
||||
E: 'ÉÈÊËĖ',
|
||||
e: 'éèêëę',
|
||||
I: 'ÍÌÎÏĮ',
|
||||
i: 'íìîïį',
|
||||
A: 'ÁÀÃÂÄĄĂÅ',
|
||||
a: 'áàãâäąăå',
|
||||
E: 'ÉÈÊËĖĚ',
|
||||
e: 'éèêëęě',
|
||||
I: 'ÍÌÎÏĮİ',
|
||||
i: 'íìîïįı',
|
||||
O: 'ÓÒÔÕÖ',
|
||||
o: 'óòôõö',
|
||||
U: 'ÚÙÛÜŪŲ',
|
||||
u: 'úùûüūų',
|
||||
U: 'ÚÙÛÜŪŲŮŰ',
|
||||
u: 'úùûüūųůű',
|
||||
C: 'ÇČĆ',
|
||||
c: 'çčć',
|
||||
D: 'Ď',
|
||||
d: 'ď',
|
||||
G: 'Ğ',
|
||||
g: 'ğ',
|
||||
L: 'Ł',
|
||||
l: 'ł',
|
||||
N: 'ÑŃ',
|
||||
n: 'ñń',
|
||||
S: 'ŠŚ',
|
||||
s: 'šś',
|
||||
Z: 'ŻŹ',
|
||||
z: 'żź'
|
||||
N: 'ÑŃŇ',
|
||||
n: 'ñńň',
|
||||
S: 'ŠŚȘŞ',
|
||||
s: 'šśșş',
|
||||
T: 'ŢȚŤ',
|
||||
t: 'ţțť',
|
||||
Y: 'Ý',
|
||||
y: 'ý',
|
||||
Z: 'ŻŹŽ',
|
||||
z: 'żźž'
|
||||
};
|
||||
|
||||
let accentsMap = new Map();
|
||||
// str.normalize("NFD").replace(/\p{Diacritic}/gu, "")
|
||||
|
||||
let accentsMap = {};
|
||||
let accentsTpl = '';
|
||||
|
||||
for (let r in accents) {
|
||||
accents[r].split('').forEach(a => {
|
||||
accentsTpl += a;
|
||||
accentsMap.set(a, r);
|
||||
accentsMap[a] = r;
|
||||
});
|
||||
}
|
||||
|
||||
let accentsRe = new RegExp(`[${accentsTpl}]`, 'g');
|
||||
let replacer = m => accentsMap.get(m);
|
||||
let replacer = m => accentsMap[m];
|
||||
|
||||
return strings => {
|
||||
if (typeof strings == 'string')
|
||||
@@ -0,0 +1 @@
|
||||
*.js
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,13 @@
|
||||
import { domToBlob } from "./4.6.6/dist/index.mjs";
|
||||
|
||||
/**
|
||||
* @param {Element} element
|
||||
*/
|
||||
export async function screenshot(element) {
|
||||
const blob = await domToBlob(element, {
|
||||
scale: 2,
|
||||
});
|
||||
const url = URL.createObjectURL(blob);
|
||||
window.open(url, "_blank");
|
||||
setTimeout(() => URL.revokeObjectURL(url), 100);
|
||||
}
|
||||
@@ -386,10 +386,10 @@ main() {
|
||||
|
||||
# Check if the directory already exists and has content
|
||||
if [[ -d "$output_dir" ]] && [[ -n "$(ls -A "$output_dir" 2>/dev/null)" ]]; then
|
||||
print_error "Directory already exists and is not empty: $output_dir"
|
||||
print_error "Package $package_name@$resolved_version appears to already be downloaded."
|
||||
print_error "Remove the directory or choose a different output location to proceed."
|
||||
exit 1
|
||||
print_warning "Directory already exists and is not empty: $output_dir"
|
||||
print_warning "Package $package_name@$resolved_version appears to already be downloaded."
|
||||
print_warning "Remove the directory or choose a different output location to proceed."
|
||||
return
|
||||
fi
|
||||
|
||||
# Create the base output directory
|
||||
@@ -409,3 +409,4 @@ main "@solidjs/signals"
|
||||
main "@leeoniya/ufuzzy"
|
||||
main "lean-qr"
|
||||
main "lightweight-charts"
|
||||
main "modern-screenshot"
|
||||
|
||||
@@ -21,6 +21,7 @@ const CANDLE = "candle";
|
||||
* @param {Elements} args.elements
|
||||
* @param {VecsResources} args.vecsResources
|
||||
* @param {VecIdToIndexes} args.vecIdToIndexes
|
||||
* @param {Packages} args.packages
|
||||
*/
|
||||
export function init({
|
||||
colors,
|
||||
@@ -32,6 +33,7 @@ export function init({
|
||||
webSockets,
|
||||
vecsResources,
|
||||
vecIdToIndexes,
|
||||
packages,
|
||||
}) {
|
||||
elements.charts.append(utils.dom.createShadow("left"));
|
||||
elements.charts.append(utils.dom.createShadow("right"));
|
||||
@@ -95,6 +97,33 @@ export function init({
|
||||
},
|
||||
});
|
||||
|
||||
const chartBottomRightCanvas = Array.from(
|
||||
chart.inner.chartElement().getElementsByTagName("tr"),
|
||||
).at(-1)?.lastChild?.firstChild?.firstChild;
|
||||
if (chartBottomRightCanvas) {
|
||||
const charts = elements.charts;
|
||||
const domain = window.document.createElement("p");
|
||||
domain.innerText = `${window.location.host}`;
|
||||
domain.id = "domain";
|
||||
const screenshotButton = window.document.createElement("button");
|
||||
screenshotButton.id = "screenshot";
|
||||
const camera = "[ ◉¯]";
|
||||
screenshotButton.innerHTML = camera;
|
||||
screenshotButton.title = "Screenshot";
|
||||
chartBottomRightCanvas.replaceWith(screenshotButton);
|
||||
screenshotButton.addEventListener("click", () => {
|
||||
packages.modernScreenshot().then(async ({ screenshot }) => {
|
||||
elements.body.dataset.screenshot = "true";
|
||||
charts.append(domain);
|
||||
seriesTypeField.hidden = true;
|
||||
await screenshot(charts);
|
||||
charts.removeChild(domain);
|
||||
seriesTypeField.hidden = false;
|
||||
elements.body.dataset.screenshot = "false";
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
chart.inner.timeScale().subscribeVisibleLogicalRangeChange(
|
||||
utils.debounce((t) => {
|
||||
if (t) {
|
||||
@@ -525,6 +554,12 @@ function createIndexSelector({ option, vecIdToIndexes, signals, utils }) {
|
||||
});
|
||||
|
||||
const fieldset = window.document.createElement("fieldset");
|
||||
fieldset.id = "interval";
|
||||
|
||||
const screenshotSpan = window.document.createElement("span");
|
||||
screenshotSpan.innerText = "interval:";
|
||||
fieldset.append(screenshotSpan);
|
||||
|
||||
fieldset.append(field);
|
||||
fieldset.dataset.size = "sm";
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
/**
|
||||
* @import { Option, PartialChartOption, ChartOption, AnyPartialOption, ProcessedOptionAddons, OptionsTree, SimulationOption, AnySeriesBlueprint, SeriesType } from "./options"
|
||||
* @import { Valued, SingleValueData, CandlestickData, OHLCTuple, Series, ISeries, HistogramData, LineData, BaselineData, LineSeriesPartialOptions, BaselineSeriesPartialOptions, HistogramSeriesPartialOptions, CandlestickSeriesPartialOptions } from "../packages/lightweight-charts/wrapper"
|
||||
* @import * as _ from "../packages/leeoniya-ufuzzy/1.0.18/dist/uFuzzy.d.ts"
|
||||
* @import * as _ from "../packages/leeoniya-ufuzzy/1.0.19/dist/uFuzzy.d.ts"
|
||||
* @import { SerializedChartableIndex } from "./chart";
|
||||
* @import { Signal, Signals, Accessor } from "../packages/solidjs-signals/wrapper";
|
||||
* @import { DateIndex, DecadeIndex, DifficultyEpoch, Index, HalvingEpoch, Height, MonthIndex, P2PK33AddressIndex, P2PK65AddressIndex, P2PKHAddressIndex, P2SHAddressIndex, P2MSOutputIndex, P2AAddressIndex, P2TRAddressIndex, P2WPKHAddressIndex, P2WSHAddressIndex, TxIndex, InputIndex, OutputIndex, VecId, WeekIndex, SemesterIndex, YearIndex, VecIdToIndexes, QuarterIndex, EmptyOutputIndex, OpReturnIndex, UnknownOutputIndex } from "./vecid-to-indexes"
|
||||
@@ -78,10 +78,13 @@ function initPackages() {
|
||||
return import("../packages/lean-qr/2.5.0/index.mjs").then((d) => d);
|
||||
},
|
||||
async ufuzzy() {
|
||||
return import("../packages/leeoniya-ufuzzy/1.0.18/dist/uFuzzy.mjs").then(
|
||||
return import("../packages/leeoniya-ufuzzy/1.0.19/dist/uFuzzy.mjs").then(
|
||||
({ default: d }) => d,
|
||||
);
|
||||
},
|
||||
async modernScreenshot() {
|
||||
return import("../packages/modern-screenshot/wrapper.js").then((d) => d);
|
||||
},
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -106,6 +109,7 @@ function initPackages() {
|
||||
lightweightCharts: importPackage("lightweightCharts"),
|
||||
leanQr: importPackage("leanQr"),
|
||||
ufuzzy: importPackage("ufuzzy"),
|
||||
modernScreenshot: importPackage("modernScreenshot"),
|
||||
};
|
||||
}
|
||||
/**
|
||||
@@ -2282,6 +2286,7 @@ function main() {
|
||||
webSockets,
|
||||
vecsResources,
|
||||
vecIdToIndexes,
|
||||
packages,
|
||||
}),
|
||||
),
|
||||
),
|
||||
|
||||
Reference in New Issue
Block a user