(beta) butterchurn visualizer
This commit is contained in:
parent
c484148078
commit
cc6c600817
6 changed files with 2981 additions and 3756 deletions
2181
index.html
2181
index.html
File diff suppressed because one or more lines are too long
|
|
@ -635,6 +635,7 @@ export const visualizerSettings = {
|
||||||
ENABLED_KEY: 'visualizer-enabled',
|
ENABLED_KEY: 'visualizer-enabled',
|
||||||
MODE_KEY: 'visualizer-mode', // 'solid' or 'blended'
|
MODE_KEY: 'visualizer-mode', // 'solid' or 'blended'
|
||||||
PRESET_KEY: 'visualizer-preset',
|
PRESET_KEY: 'visualizer-preset',
|
||||||
|
BUTTERCHURN_CYCLE_KEY: 'butterchurn-cycle-duration',
|
||||||
|
|
||||||
getPreset() {
|
getPreset() {
|
||||||
try {
|
try {
|
||||||
|
|
@ -699,6 +700,20 @@ export const visualizerSettings = {
|
||||||
setSmartIntensity(enabled) {
|
setSmartIntensity(enabled) {
|
||||||
localStorage.setItem(this.SMART_INTENSITY_KEY, enabled);
|
localStorage.setItem(this.SMART_INTENSITY_KEY, enabled);
|
||||||
},
|
},
|
||||||
|
|
||||||
|
// Butterchurn preset cycle duration in seconds (0 = disabled)
|
||||||
|
getButterchurnCycleDuration() {
|
||||||
|
try {
|
||||||
|
const val = localStorage.getItem(this.BUTTERCHURN_CYCLE_KEY);
|
||||||
|
return val ? parseInt(val, 10) : 30;
|
||||||
|
} catch {
|
||||||
|
return 30;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
setButterchurnCycleDuration(seconds) {
|
||||||
|
localStorage.setItem(this.BUTTERCHURN_CYCLE_KEY, seconds.toString());
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
export const equalizerSettings = {
|
export const equalizerSettings = {
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,7 @@ import { visualizerSettings } from './storage.js';
|
||||||
import { LCDPreset } from './visualizers/lcd.js';
|
import { LCDPreset } from './visualizers/lcd.js';
|
||||||
import { ParticlesPreset } from './visualizers/particles.js';
|
import { ParticlesPreset } from './visualizers/particles.js';
|
||||||
import { UnknownPleasuresWebGL } from './visualizers/unknown_pleasures_webgl.js';
|
import { UnknownPleasuresWebGL } from './visualizers/unknown_pleasures_webgl.js';
|
||||||
|
import { ButterchurnPreset } from './visualizers/butterchurn.js';
|
||||||
import { audioContextManager } from './audio-context.js';
|
import { audioContextManager } from './audio-context.js';
|
||||||
|
|
||||||
export class Visualizer {
|
export class Visualizer {
|
||||||
|
|
@ -21,6 +22,7 @@ export class Visualizer {
|
||||||
lcd: new LCDPreset(),
|
lcd: new LCDPreset(),
|
||||||
particles: new ParticlesPreset(),
|
particles: new ParticlesPreset(),
|
||||||
'unknown-pleasures': new UnknownPleasuresWebGL(),
|
'unknown-pleasures': new UnknownPleasuresWebGL(),
|
||||||
|
butterchurn: new ButterchurnPreset(),
|
||||||
};
|
};
|
||||||
|
|
||||||
this.activePresetKey = visualizerSettings.getPreset();
|
this.activePresetKey = visualizerSettings.getPreset();
|
||||||
|
|
@ -139,6 +141,15 @@ export class Visualizer {
|
||||||
this.audioContext.resume();
|
this.audioContext.resume();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Initialize Butterchurn if it's the active preset
|
||||||
|
if (this.activePresetKey === 'butterchurn' && this.activePreset.lazyInit) {
|
||||||
|
this.activePreset.lazyInit(
|
||||||
|
this.canvas,
|
||||||
|
this.audioContext,
|
||||||
|
audioContextManager.source
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
this.resize();
|
this.resize();
|
||||||
window.addEventListener('resize', this._resizeBound);
|
window.addEventListener('resize', this._resizeBound);
|
||||||
this.canvas.style.display = 'block';
|
this.canvas.style.display = 'block';
|
||||||
|
|
@ -258,5 +269,14 @@ export class Visualizer {
|
||||||
this.activePresetKey = key;
|
this.activePresetKey = key;
|
||||||
this.initContext();
|
this.initContext();
|
||||||
this.resize();
|
this.resize();
|
||||||
|
|
||||||
|
// Initialize Butterchurn if switching to it
|
||||||
|
if (key === 'butterchurn' && this.presets[key].lazyInit && this.audioContext) {
|
||||||
|
this.presets[key].lazyInit(
|
||||||
|
this.canvas,
|
||||||
|
this.audioContext,
|
||||||
|
audioContextManager.source
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
259
js/visualizers/butterchurn.js
Normal file
259
js/visualizers/butterchurn.js
Normal file
|
|
@ -0,0 +1,259 @@
|
||||||
|
/**
|
||||||
|
* Butterchurn (Milkdrop) Visualizer Preset
|
||||||
|
* WebGL-based audio visualization using the Butterchurn library
|
||||||
|
*/
|
||||||
|
import butterchurn from 'butterchurn';
|
||||||
|
import butterchurnPresets from 'butterchurn-presets';
|
||||||
|
import { visualizerSettings } from '../storage.js';
|
||||||
|
|
||||||
|
export class ButterchurnPreset {
|
||||||
|
constructor() {
|
||||||
|
this.name = 'Butterchurn';
|
||||||
|
this.contextType = 'webgl';
|
||||||
|
|
||||||
|
this.visualizer = null;
|
||||||
|
this.canvas = null;
|
||||||
|
this.audioContext = null;
|
||||||
|
this.presets = null;
|
||||||
|
this.presetKeys = [];
|
||||||
|
this.currentPresetIndex = 0;
|
||||||
|
this.lastPresetChange = 0;
|
||||||
|
this.isInitialized = false;
|
||||||
|
|
||||||
|
// Transition settings
|
||||||
|
this.blendProgress = 0;
|
||||||
|
this.blendDuration = 2.7; // seconds for preset transitions
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the preset cycle duration from settings (in milliseconds)
|
||||||
|
*/
|
||||||
|
getPresetDuration() {
|
||||||
|
const seconds = visualizerSettings.getButterchurnCycleDuration();
|
||||||
|
return seconds * 1000; // Convert to milliseconds
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initialize Butterchurn with the given WebGL context
|
||||||
|
*/
|
||||||
|
init(canvas, gl, audioContext, sourceNode) {
|
||||||
|
if (this.isInitialized) return;
|
||||||
|
|
||||||
|
try {
|
||||||
|
this.canvas = canvas;
|
||||||
|
this.audioContext = audioContext;
|
||||||
|
|
||||||
|
// Load presets
|
||||||
|
this.presets = butterchurnPresets.getPresets();
|
||||||
|
this.presetKeys = Object.keys(this.presets);
|
||||||
|
|
||||||
|
// Filter to get a good selection of presets (some are better than others)
|
||||||
|
this.presetKeys = this.presetKeys.filter(key => {
|
||||||
|
// Skip some problematic or less visually appealing presets
|
||||||
|
const skipPatterns = ['flexi', 'empty', 'test', '_'];
|
||||||
|
return !skipPatterns.some(pattern => key.toLowerCase().includes(pattern));
|
||||||
|
});
|
||||||
|
|
||||||
|
if (this.presetKeys.length === 0) {
|
||||||
|
this.presetKeys = Object.keys(this.presets);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Shuffle presets for variety
|
||||||
|
this.shufflePresets();
|
||||||
|
|
||||||
|
// Create Butterchurn visualizer
|
||||||
|
this.visualizer = butterchurn.createVisualizer(audioContext, canvas, {
|
||||||
|
width: canvas.width,
|
||||||
|
height: canvas.height,
|
||||||
|
pixelRatio: window.devicePixelRatio || 1,
|
||||||
|
textureRatio: 1,
|
||||||
|
});
|
||||||
|
|
||||||
|
// Connect audio source
|
||||||
|
if (sourceNode) {
|
||||||
|
this.visualizer.connectAudio(sourceNode);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Load initial preset
|
||||||
|
this.loadRandomPreset();
|
||||||
|
|
||||||
|
this.lastPresetChange = performance.now();
|
||||||
|
this.isInitialized = true;
|
||||||
|
|
||||||
|
console.log('[Butterchurn] Initialized with', this.presetKeys.length, 'presets');
|
||||||
|
} catch (error) {
|
||||||
|
console.error('[Butterchurn] Initialization failed:', error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Shuffle the preset keys for random variety
|
||||||
|
*/
|
||||||
|
shufflePresets() {
|
||||||
|
for (let i = this.presetKeys.length - 1; i > 0; i--) {
|
||||||
|
const j = Math.floor(Math.random() * (i + 1));
|
||||||
|
[this.presetKeys[i], this.presetKeys[j]] = [this.presetKeys[j], this.presetKeys[i]];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Load a random preset with smooth transition
|
||||||
|
*/
|
||||||
|
loadRandomPreset() {
|
||||||
|
if (!this.visualizer || this.presetKeys.length === 0) return;
|
||||||
|
|
||||||
|
this.currentPresetIndex = (this.currentPresetIndex + 1) % this.presetKeys.length;
|
||||||
|
const presetKey = this.presetKeys[this.currentPresetIndex];
|
||||||
|
const preset = this.presets[presetKey];
|
||||||
|
|
||||||
|
if (preset) {
|
||||||
|
try {
|
||||||
|
this.visualizer.loadPreset(preset, this.blendDuration);
|
||||||
|
console.log('[Butterchurn] Loaded preset:', presetKey);
|
||||||
|
} catch (error) {
|
||||||
|
console.warn('[Butterchurn] Failed to load preset:', presetKey, error);
|
||||||
|
// Try next preset
|
||||||
|
if (this.presetKeys.length > 1) {
|
||||||
|
this.presetKeys.splice(this.currentPresetIndex, 1);
|
||||||
|
this.loadRandomPreset();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Load a specific preset by name
|
||||||
|
*/
|
||||||
|
loadPreset(presetName) {
|
||||||
|
if (!this.visualizer || !this.presets) return;
|
||||||
|
|
||||||
|
const preset = this.presets[presetName];
|
||||||
|
if (preset) {
|
||||||
|
this.visualizer.loadPreset(preset, this.blendDuration);
|
||||||
|
console.log('[Butterchurn] Loaded preset:', presetName);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get list of available preset names
|
||||||
|
*/
|
||||||
|
getPresetNames() {
|
||||||
|
return this.presetKeys;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get current preset name
|
||||||
|
*/
|
||||||
|
getCurrentPresetName() {
|
||||||
|
return this.presetKeys[this.currentPresetIndex] || 'Unknown';
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Skip to next preset
|
||||||
|
*/
|
||||||
|
nextPreset() {
|
||||||
|
this.loadRandomPreset();
|
||||||
|
this.lastPresetChange = performance.now();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Resize handler
|
||||||
|
*/
|
||||||
|
resize(width, height) {
|
||||||
|
if (this.visualizer) {
|
||||||
|
this.visualizer.setRendererSize(width, height);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Main draw function called each animation frame
|
||||||
|
*/
|
||||||
|
draw(ctx, canvas, analyser, dataArray, params) {
|
||||||
|
if (!this.isInitialized) {
|
||||||
|
// Lazy initialization - need audio context and source node
|
||||||
|
// This will be handled by the visualizer.js main class
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!this.visualizer) return;
|
||||||
|
|
||||||
|
const { mode } = params;
|
||||||
|
const now = performance.now();
|
||||||
|
|
||||||
|
// Auto-cycle presets (if cycle duration > 0)
|
||||||
|
const cycleDuration = this.getPresetDuration();
|
||||||
|
if (cycleDuration > 0 && now - this.lastPresetChange > cycleDuration) {
|
||||||
|
this.loadRandomPreset();
|
||||||
|
this.lastPresetChange = now;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Render the visualization
|
||||||
|
try {
|
||||||
|
this.visualizer.render();
|
||||||
|
} catch (error) {
|
||||||
|
console.warn('[Butterchurn] Render error:', error);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Handle blended mode - we need to composite with cover art
|
||||||
|
// Butterchurn renders directly to the canvas, so for blended mode
|
||||||
|
// we need to adjust the canvas opacity/blend
|
||||||
|
if (mode === 'blended') {
|
||||||
|
// The canvas will be composited by CSS in the parent
|
||||||
|
canvas.style.opacity = '0.85';
|
||||||
|
canvas.style.mixBlendMode = 'screen';
|
||||||
|
} else {
|
||||||
|
canvas.style.opacity = '1';
|
||||||
|
canvas.style.mixBlendMode = 'normal';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Connect audio source to the visualizer
|
||||||
|
*/
|
||||||
|
connectAudio(sourceNode) {
|
||||||
|
if (this.visualizer && sourceNode) {
|
||||||
|
try {
|
||||||
|
this.visualizer.connectAudio(sourceNode);
|
||||||
|
console.log('[Butterchurn] Audio connected');
|
||||||
|
} catch (error) {
|
||||||
|
console.warn('[Butterchurn] Failed to connect audio:', error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Lazy initialization helper for when audio context becomes available
|
||||||
|
*/
|
||||||
|
lazyInit(canvas, audioContext, sourceNode) {
|
||||||
|
if (!this.isInitialized && canvas && audioContext) {
|
||||||
|
const gl = canvas.getContext('webgl2', {
|
||||||
|
alpha: true,
|
||||||
|
antialias: true,
|
||||||
|
preserveDrawingBuffer: true,
|
||||||
|
}) || canvas.getContext('webgl', {
|
||||||
|
alpha: true,
|
||||||
|
antialias: true,
|
||||||
|
preserveDrawingBuffer: true,
|
||||||
|
});
|
||||||
|
|
||||||
|
if (gl) {
|
||||||
|
this.init(canvas, gl, audioContext, sourceNode);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Cleanup resources
|
||||||
|
*/
|
||||||
|
destroy() {
|
||||||
|
if (this.visualizer) {
|
||||||
|
// Butterchurn doesn't have an explicit cleanup method
|
||||||
|
// but we can null our references
|
||||||
|
this.visualizer = null;
|
||||||
|
}
|
||||||
|
this.isInitialized = false;
|
||||||
|
this.canvas = null;
|
||||||
|
this.audioContext = null;
|
||||||
|
console.log('[Butterchurn] Destroyed');
|
||||||
|
}
|
||||||
|
}
|
||||||
70
package-lock.json
generated
70
package-lock.json
generated
|
|
@ -9,6 +9,8 @@
|
||||||
"version": "1.0.0",
|
"version": "1.0.0",
|
||||||
"license": "ISC",
|
"license": "ISC",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
"butterchurn": "^2.6.7",
|
||||||
|
"butterchurn-presets": "^2.4.7",
|
||||||
"dashjs": "^5.1.1",
|
"dashjs": "^5.1.1",
|
||||||
"pocketbase": "^0.26.5"
|
"pocketbase": "^0.26.5"
|
||||||
},
|
},
|
||||||
|
|
@ -74,6 +76,7 @@
|
||||||
"integrity": "sha512-e7jT4DxYvIDLk1ZHmU/m/mB19rex9sv0c2ftBtjSBv+kVM/902eh0fINUzD7UwLLNR+jU585GxUJ8/EBfAM5fw==",
|
"integrity": "sha512-e7jT4DxYvIDLk1ZHmU/m/mB19rex9sv0c2ftBtjSBv+kVM/902eh0fINUzD7UwLLNR+jU585GxUJ8/EBfAM5fw==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
|
"peer": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@babel/code-frame": "^7.27.1",
|
"@babel/code-frame": "^7.27.1",
|
||||||
"@babel/generator": "^7.28.5",
|
"@babel/generator": "^7.28.5",
|
||||||
|
|
@ -1513,7 +1516,6 @@
|
||||||
"version": "7.28.4",
|
"version": "7.28.4",
|
||||||
"resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.28.4.tgz",
|
"resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.28.4.tgz",
|
||||||
"integrity": "sha512-Q/N6JNWvIvPnLDvjlE1OUBLPQHH6l3CltCEsHIujp45zQUSSh8K+gHnaEX45yAT1nyngnINhvWtzN+Nb9D8RAQ==",
|
"integrity": "sha512-Q/N6JNWvIvPnLDvjlE1OUBLPQHH6l3CltCEsHIujp45zQUSSh8K+gHnaEX45yAT1nyngnINhvWtzN+Nb9D8RAQ==",
|
||||||
"dev": true,
|
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=6.9.0"
|
"node": ">=6.9.0"
|
||||||
|
|
@ -1603,6 +1605,7 @@
|
||||||
"integrity": "sha512-FA5LmZVF1VziNc0bIdCSA1IoSVnDCqE8HJIZZv2/W8YmoAM50+tnUgJR/gQZwEeIMleuIOnRnHA/UaZRNeV4iQ==",
|
"integrity": "sha512-FA5LmZVF1VziNc0bIdCSA1IoSVnDCqE8HJIZZv2/W8YmoAM50+tnUgJR/gQZwEeIMleuIOnRnHA/UaZRNeV4iQ==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
|
"peer": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@keyv/serialize": "^1.1.1"
|
"@keyv/serialize": "^1.1.1"
|
||||||
}
|
}
|
||||||
|
|
@ -1644,6 +1647,7 @@
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
|
"peer": true,
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=18"
|
"node": ">=18"
|
||||||
},
|
},
|
||||||
|
|
@ -1687,6 +1691,7 @@
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
|
"peer": true,
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=18"
|
"node": ">=18"
|
||||||
}
|
}
|
||||||
|
|
@ -3138,6 +3143,7 @@
|
||||||
"resolved": "https://registry.npmjs.org/@svta/cml-xml/-/cml-xml-1.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/@svta/cml-xml/-/cml-xml-1.0.1.tgz",
|
||||||
"integrity": "sha512-11LkJa5kDEcsRMWkVI1ABH3KLCxGoiSVe4kQ293ItVj8ncTTQ7htmCGiJDjS+Cmy35UgF3e/vc0ysJIiWRTx2g==",
|
"integrity": "sha512-11LkJa5kDEcsRMWkVI1ABH3KLCxGoiSVe4kQ293ItVj8ncTTQ7htmCGiJDjS+Cmy35UgF3e/vc0ysJIiWRTx2g==",
|
||||||
"license": "Apache-2.0",
|
"license": "Apache-2.0",
|
||||||
|
"peer": true,
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=20"
|
"node": ">=20"
|
||||||
},
|
},
|
||||||
|
|
@ -3186,6 +3192,7 @@
|
||||||
"integrity": "sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==",
|
"integrity": "sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
|
"peer": true,
|
||||||
"bin": {
|
"bin": {
|
||||||
"acorn": "bin/acorn"
|
"acorn": "bin/acorn"
|
||||||
},
|
},
|
||||||
|
|
@ -3209,6 +3216,7 @@
|
||||||
"integrity": "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==",
|
"integrity": "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
|
"peer": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"fast-deep-equal": "^3.1.3",
|
"fast-deep-equal": "^3.1.3",
|
||||||
"fast-uri": "^3.0.1",
|
"fast-uri": "^3.0.1",
|
||||||
|
|
@ -3397,6 +3405,16 @@
|
||||||
"@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0"
|
"@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/babel-runtime": {
|
||||||
|
"version": "6.26.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/babel-runtime/-/babel-runtime-6.26.0.tgz",
|
||||||
|
"integrity": "sha512-ITKNuq2wKlW1fJg9sSW52eepoYgZBggvOAHC0u/CYu/qxQ9EVzThCgR69BnSXLHjy2f7SY5zaQ4yt7H9ZVxY2g==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"core-js": "^2.4.0",
|
||||||
|
"regenerator-runtime": "^0.11.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/balanced-match": {
|
"node_modules/balanced-match": {
|
||||||
"version": "1.0.2",
|
"version": "1.0.2",
|
||||||
"resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz",
|
"resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz",
|
||||||
|
|
@ -3496,6 +3514,7 @@
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
|
"peer": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"baseline-browser-mapping": "^2.9.0",
|
"baseline-browser-mapping": "^2.9.0",
|
||||||
"caniuse-lite": "^1.0.30001759",
|
"caniuse-lite": "^1.0.30001759",
|
||||||
|
|
@ -3517,6 +3536,27 @@
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
|
"node_modules/butterchurn": {
|
||||||
|
"version": "2.6.7",
|
||||||
|
"resolved": "https://registry.npmjs.org/butterchurn/-/butterchurn-2.6.7.tgz",
|
||||||
|
"integrity": "sha512-BJiRA8L0L2+84uoG2SSfkp0kclBuN+vQKf217pK7pMlwEO2ZEg3MtO2/o+l8Qpr8Nbejg8tmL1ZHD1jmhiaaqg==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"@babel/runtime": "^7.0.0",
|
||||||
|
"ecma-proposal-math-extensions": "0.0.2"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/butterchurn-presets": {
|
||||||
|
"version": "2.4.7",
|
||||||
|
"resolved": "https://registry.npmjs.org/butterchurn-presets/-/butterchurn-presets-2.4.7.tgz",
|
||||||
|
"integrity": "sha512-4MdM8ripz/VfH1BCldrIKdAc/1ryJFBDvqlyow6Ivo1frwj0H3duzvSMFC7/wIjAjxb1QpwVHVqGqS9uAFKhpg==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"babel-runtime": "^6.26.0",
|
||||||
|
"ecma-proposal-math-extensions": "0.0.2",
|
||||||
|
"lodash": "^4.17.4"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/cacheable": {
|
"node_modules/cacheable": {
|
||||||
"version": "2.3.1",
|
"version": "2.3.1",
|
||||||
"resolved": "https://registry.npmjs.org/cacheable/-/cacheable-2.3.1.tgz",
|
"resolved": "https://registry.npmjs.org/cacheable/-/cacheable-2.3.1.tgz",
|
||||||
|
|
@ -3719,6 +3759,14 @@
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
|
"node_modules/core-js": {
|
||||||
|
"version": "2.6.12",
|
||||||
|
"resolved": "https://registry.npmjs.org/core-js/-/core-js-2.6.12.tgz",
|
||||||
|
"integrity": "sha512-Kb2wC0fvsWfQrgk8HU5lW6U/Lcs8+9aaYcy4ZFc6DDlo4nZ7n70dEgE5rtR0oG6ufKDUnrwfWL1mXR5ljDatrQ==",
|
||||||
|
"deprecated": "core-js@<3.23.3 is no longer maintained and not recommended for usage due to the number of issues. Because of the V8 engine whims, feature detection in old core-js versions could cause a slowdown up to 100x even if nothing is polyfilled. Some versions have web compatibility issues. Please, upgrade your dependencies to the actual version of core-js.",
|
||||||
|
"hasInstallScript": true,
|
||||||
|
"license": "MIT"
|
||||||
|
},
|
||||||
"node_modules/core-js-compat": {
|
"node_modules/core-js-compat": {
|
||||||
"version": "3.47.0",
|
"version": "3.47.0",
|
||||||
"resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.47.0.tgz",
|
"resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.47.0.tgz",
|
||||||
|
|
@ -4006,6 +4054,12 @@
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
|
"node_modules/ecma-proposal-math-extensions": {
|
||||||
|
"version": "0.0.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/ecma-proposal-math-extensions/-/ecma-proposal-math-extensions-0.0.2.tgz",
|
||||||
|
"integrity": "sha512-80BnDp2Fn7RxXlEr5HHZblniY4aQ97MOAicdWWpSo0vkQiISSE9wLR4SqxKsu4gCtXFBIPPzy8JMhay4NWRg/Q==",
|
||||||
|
"license": "MIT"
|
||||||
|
},
|
||||||
"node_modules/ejs": {
|
"node_modules/ejs": {
|
||||||
"version": "3.1.10",
|
"version": "3.1.10",
|
||||||
"resolved": "https://registry.npmjs.org/ejs/-/ejs-3.1.10.tgz",
|
"resolved": "https://registry.npmjs.org/ejs/-/ejs-3.1.10.tgz",
|
||||||
|
|
@ -4280,6 +4334,7 @@
|
||||||
"integrity": "sha512-LEyamqS7W5HB3ujJyvi0HQK/dtVINZvd5mAAp9eT5S/ujByGjiZLCzPcHVzuXbpJDJF/cxwHlfceVUDZ2lnSTw==",
|
"integrity": "sha512-LEyamqS7W5HB3ujJyvi0HQK/dtVINZvd5mAAp9eT5S/ujByGjiZLCzPcHVzuXbpJDJF/cxwHlfceVUDZ2lnSTw==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
|
"peer": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@eslint-community/eslint-utils": "^4.8.0",
|
"@eslint-community/eslint-utils": "^4.8.0",
|
||||||
"@eslint-community/regexpp": "^4.12.1",
|
"@eslint-community/regexpp": "^4.12.1",
|
||||||
|
|
@ -6124,7 +6179,6 @@
|
||||||
"version": "4.17.23",
|
"version": "4.17.23",
|
||||||
"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.23.tgz",
|
"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.23.tgz",
|
||||||
"integrity": "sha512-LgVTMpQtIopCi79SJeDiP0TfWi5CNEc/L/aRdTh3yIvmZXTnheWpKjSZhnvMl8iXbC1tFg9gdHHDMLoV7CnG+w==",
|
"integrity": "sha512-LgVTMpQtIopCi79SJeDiP0TfWi5CNEc/L/aRdTh3yIvmZXTnheWpKjSZhnvMl8iXbC1tFg9gdHHDMLoV7CnG+w==",
|
||||||
"dev": true,
|
|
||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
"node_modules/lodash.debounce": {
|
"node_modules/lodash.debounce": {
|
||||||
|
|
@ -6636,6 +6690,7 @@
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
|
"peer": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"nanoid": "^3.3.11",
|
"nanoid": "^3.3.11",
|
||||||
"picocolors": "^1.1.1",
|
"picocolors": "^1.1.1",
|
||||||
|
|
@ -6719,6 +6774,7 @@
|
||||||
"integrity": "sha512-orRsuYpJVw8LdAwqqLykBj9ecS5/cRHlI5+nvTo8LcCKmzDmqVORXtOIYEEQuL9D4BxtA1lm5isAqzQZCoQ6Eg==",
|
"integrity": "sha512-orRsuYpJVw8LdAwqqLykBj9ecS5/cRHlI5+nvTo8LcCKmzDmqVORXtOIYEEQuL9D4BxtA1lm5isAqzQZCoQ6Eg==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
|
"peer": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"cssesc": "^3.0.0",
|
"cssesc": "^3.0.0",
|
||||||
"util-deprecate": "^1.0.2"
|
"util-deprecate": "^1.0.2"
|
||||||
|
|
@ -6870,6 +6926,12 @@
|
||||||
"node": ">=4"
|
"node": ">=4"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/regenerator-runtime": {
|
||||||
|
"version": "0.11.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.11.1.tgz",
|
||||||
|
"integrity": "sha512-MguG95oij0fC3QV3URf4V2SDYGJhJnJGqvIIgdECeODCT98wSWDAJ94SSuVpYQUoTcGUIL6L4yNB7j1DFFHSBg==",
|
||||||
|
"license": "MIT"
|
||||||
|
},
|
||||||
"node_modules/regexp.prototype.flags": {
|
"node_modules/regexp.prototype.flags": {
|
||||||
"version": "1.5.4",
|
"version": "1.5.4",
|
||||||
"resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.5.4.tgz",
|
"resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.5.4.tgz",
|
||||||
|
|
@ -7668,6 +7730,7 @@
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
|
"peer": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@csstools/css-parser-algorithms": "^3.0.5",
|
"@csstools/css-parser-algorithms": "^3.0.5",
|
||||||
"@csstools/css-syntax-patches-for-csstree": "^1.0.19",
|
"@csstools/css-syntax-patches-for-csstree": "^1.0.19",
|
||||||
|
|
@ -8082,6 +8145,7 @@
|
||||||
"integrity": "sha512-t/R3R/n0MSwnnazuPpPNVO60LX0SKL45pyl9YlvxIdkH0Of7D5qM2EVe+yASRIlY5pZ73nclYJfNANGWPwFDZw==",
|
"integrity": "sha512-t/R3R/n0MSwnnazuPpPNVO60LX0SKL45pyl9YlvxIdkH0Of7D5qM2EVe+yASRIlY5pZ73nclYJfNANGWPwFDZw==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "BSD-2-Clause",
|
"license": "BSD-2-Clause",
|
||||||
|
"peer": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@jridgewell/source-map": "^0.3.3",
|
"@jridgewell/source-map": "^0.3.3",
|
||||||
"acorn": "^8.15.0",
|
"acorn": "^8.15.0",
|
||||||
|
|
@ -8406,6 +8470,7 @@
|
||||||
"integrity": "sha512-dZwN5L1VlUBewiP6H9s2+B3e3Jg96D0vzN+Ry73sOefebhYr9f94wwkMNN/9ouoU8pV1BqA1d1zGk8928cx0rg==",
|
"integrity": "sha512-dZwN5L1VlUBewiP6H9s2+B3e3Jg96D0vzN+Ry73sOefebhYr9f94wwkMNN/9ouoU8pV1BqA1d1zGk8928cx0rg==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
|
"peer": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"esbuild": "^0.27.0",
|
"esbuild": "^0.27.0",
|
||||||
"fdir": "^6.5.0",
|
"fdir": "^6.5.0",
|
||||||
|
|
@ -8793,6 +8858,7 @@
|
||||||
"integrity": "sha512-fS6iqSPZDs3dr/y7Od6y5nha8dW1YnbgtsyotCVvoFGKbERG++CVRFv1meyGDE1SNItQA8BrnCw7ScdAhRJ3XQ==",
|
"integrity": "sha512-fS6iqSPZDs3dr/y7Od6y5nha8dW1YnbgtsyotCVvoFGKbERG++CVRFv1meyGDE1SNItQA8BrnCw7ScdAhRJ3XQ==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
|
"peer": true,
|
||||||
"bin": {
|
"bin": {
|
||||||
"rollup": "dist/bin/rollup"
|
"rollup": "dist/bin/rollup"
|
||||||
},
|
},
|
||||||
|
|
|
||||||
|
|
@ -43,7 +43,9 @@
|
||||||
"source-map": "^0.7.4"
|
"source-map": "^0.7.4"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"pocketbase": "^0.26.5",
|
"butterchurn": "^2.6.7",
|
||||||
"dashjs": "^5.1.1"
|
"butterchurn-presets": "^2.4.7",
|
||||||
|
"dashjs": "^5.1.1",
|
||||||
|
"pocketbase": "^0.26.5"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue