resig.js
Version:
Universal reactive signal library with complete platform features: signals, animations, CRDTs, scheduling, DOM integration. Works identically across React, SolidJS, Svelte, Vue, and Qwik.
288 lines • 22.8 kB
JavaScript
;
/**
* Animation Scheduler Integration
* Connects animation system with the existing scheduler for optimal frame management
*/
Object.defineProperty(exports, "__esModule", { value: true });
exports.profileAnimations = exports.debugAnimations = exports.getAnimationStats = exports.scheduledTimeline = exports.animate = exports.scheduledAnimation = exports.getGlobalAnimationManager = void 0;
const signal_1 = require("../core/signal");
const scheduler_1 = require("../scheduler");
const core_1 = require("./core");
const composer_1 = require("./composer");
// Global animation manager instance
let globalAnimationManager = null;
const getGlobalAnimationManager = () => {
if (!globalAnimationManager) {
globalAnimationManager = createAnimationManager();
}
return globalAnimationManager;
};
exports.getGlobalAnimationManager = getGlobalAnimationManager;
// Create animation manager that integrates with scheduler
const createAnimationManager = () => {
const activeAnimations = (0, signal_1.signal)(new Set());
const frameRate = (0, signal_1.signal)(60);
// let lastFrameTime = 0;
let frameCount = 0;
let fpsUpdateTime = 0;
const animations = new Map();
const animationTasks = new Map(); // animationId -> taskId
let isRunning = false;
let masterTaskId = null;
const updateFrameRate = (currentTime) => {
frameCount++;
if (currentTime - fpsUpdateTime >= 1000) {
const fps = frameCount / ((currentTime - fpsUpdateTime) / 1000);
frameRate._set(Math.round(fps));
frameCount = 0;
fpsUpdateTime = currentTime;
}
};
const animationLoop = () => {
const currentTime = performance.now();
updateFrameRate(currentTime);
// Update all active animations
const activeIds = new Set();
for (const [id, anim] of Array.from(animations.entries())) {
if (!anim.isComplete.value()) {
activeIds.add(id);
// The animation's internal update loop will handle the actual updates
// We just need to track which animations are still active
}
else {
// Animation completed, remove it
animations.delete(id);
const taskId = animationTasks.get(id);
if (taskId) {
(0, scheduler_1.cancel)(taskId);
animationTasks.delete(id);
}
}
}
activeAnimations._set(activeIds);
// Continue the loop if there are active animations
if (activeIds.size > 0) {
return Promise.resolve(); // Continue the scheduled task
}
else {
// No more animations, stop the master loop
isRunning = false;
masterTaskId = null;
return Promise.resolve(); // Stop the scheduled task
}
};
const startMasterLoop = () => {
if (!isRunning && animations.size > 0) {
isRunning = true;
fpsUpdateTime = performance.now();
frameCount = 0;
masterTaskId = (0, scheduler_1.schedule)({
priority: scheduler_1.Priority.HIGH,
repeat: true,
execute: animationLoop,
});
}
};
const stopMasterLoop = () => {
if (isRunning && masterTaskId) {
(0, scheduler_1.cancel)(masterTaskId);
isRunning = false;
masterTaskId = null;
}
};
const instance = {
activeAnimations,
frameRate,
register: (animation) => {
animations.set(animation.id, animation);
// Start the master loop if not already running
startMasterLoop();
// Set up cleanup when animation completes
animation.onComplete(() => {
animations.delete(animation.id);
const taskId = animationTasks.get(animation.id);
if (taskId) {
(0, scheduler_1.cancel)(taskId);
animationTasks.delete(animation.id);
}
// Update active animations
const current = activeAnimations.value();
const updated = new Set(current);
updated.delete(animation.id);
activeAnimations._set(updated);
// Stop master loop if no more animations
if (updated.size === 0) {
stopMasterLoop();
}
});
return animation.id;
},
unregister: (animationId) => {
const animation = animations.get(animationId);
if (animation) {
animation.stop();
animations.delete(animationId);
const taskId = animationTasks.get(animationId);
if (taskId) {
(0, scheduler_1.cancel)(taskId);
animationTasks.delete(animationId);
}
// Update active animations
const current = activeAnimations.value();
const updated = new Set(current);
updated.delete(animationId);
activeAnimations._set(updated);
return true;
}
return false;
},
pause: () => {
for (const animation of Array.from(animations.values())) {
animation.pause();
}
stopMasterLoop();
},
resume: () => {
for (const animation of Array.from(animations.values())) {
animation.resume();
}
startMasterLoop();
},
clear: () => {
for (const animation of Array.from(animations.values())) {
animation.stop();
}
for (const taskId of Array.from(animationTasks.values())) {
(0, scheduler_1.cancel)(taskId);
}
animations.clear();
animationTasks.clear();
activeAnimations._set(new Set());
stopMasterLoop();
},
};
return instance;
};
// Create a scheduled animation that integrates with the animation manager
const scheduledAnimation = (from, to, duration, interpolator, easing) => {
const baseAnimation = (0, core_1.animation)(from, to, duration, interpolator, easing);
const isScheduledSignal = (0, signal_1.signal)(false);
let taskId = null;
const instance = {
...baseAnimation,
taskId,
isScheduled: isScheduledSignal,
start: () => {
// Register with animation manager
const manager = (0, exports.getGlobalAnimationManager)();
manager.register(baseAnimation);
isScheduledSignal._set(true);
// Start the base animation
baseAnimation.start();
},
stop: () => {
// Unregister from animation manager
const manager = (0, exports.getGlobalAnimationManager)();
manager.unregister(baseAnimation.id);
isScheduledSignal._set(false);
// Stop the base animation
baseAnimation.stop();
},
pause: () => {
baseAnimation.pause();
},
resume: () => {
baseAnimation.resume();
},
};
return instance;
};
exports.scheduledAnimation = scheduledAnimation;
// Utility function to create animations that automatically integrate with scheduler
const animate = (from, to, duration, interpolator, easing) => {
return (0, exports.scheduledAnimation)(from, to, duration, interpolator, easing);
};
exports.animate = animate;
// Timeline that integrates with scheduler
const scheduledTimeline = () => {
const baseTimeline = (0, composer_1.timeline)();
let isRegistered = false;
const register = () => {
if (!isRegistered) {
const manager = (0, exports.getGlobalAnimationManager)();
// Register a dummy animation to keep the manager active
const dummyAnim = (0, core_1.animation)(0, 1, baseTimeline.duration, (_f, _t, p) => p);
manager.register(dummyAnim);
isRegistered = true;
}
};
const unregister = () => {
if (isRegistered) {
// Timeline cleanup is handled by the base timeline
isRegistered = false;
}
};
return {
...baseTimeline,
register,
unregister,
start: () => {
register();
baseTimeline.start();
},
stop: () => {
unregister();
baseTimeline.stop();
},
};
};
exports.scheduledTimeline = scheduledTimeline;
// Performance monitoring utilities
const getAnimationStats = () => {
const manager = (0, exports.getGlobalAnimationManager)();
return {
activeCount: manager.activeAnimations.value().size,
frameRate: manager.frameRate.value(),
scheduler: (0, scheduler_1.getGlobalScheduler)().state.value(),
};
};
exports.getAnimationStats = getAnimationStats;
// Debug utilities
const debugAnimations = () => {
const manager = (0, exports.getGlobalAnimationManager)();
const stats = (0, exports.getAnimationStats)();
console.group('Animation Debug Info');
console.log('Active Animations:', stats.activeCount);
console.log('Frame Rate:', stats.frameRate, 'fps');
console.log('Scheduler State:', stats.scheduler);
console.log('Active Animation IDs:', Array.from(manager.activeAnimations.value()));
console.groupEnd();
};
exports.debugAnimations = debugAnimations;
// Animation performance profiler
const profileAnimations = (duration = 5000) => {
const manager = (0, exports.getGlobalAnimationManager)();
const startTime = performance.now();
const samples = [];
const sampleInterval = setInterval(() => {
const currentTime = performance.now();
samples.push({
time: currentTime - startTime,
count: manager.activeAnimations.value().size,
fps: manager.frameRate.value(),
});
}, 100);
setTimeout(() => {
clearInterval(sampleInterval);
console.group('Animation Performance Profile');
console.table(samples);
const avgFps = samples.reduce((sum, s) => sum + s.fps, 0) / samples.length;
const maxAnimations = Math.max(...samples.map((s) => s.count));
console.log('Average FPS:', avgFps.toFixed(2));
console.log('Max Concurrent Animations:', maxAnimations);
console.groupEnd();
}, duration);
return () => clearInterval(sampleInterval);
};
exports.profileAnimations = profileAnimations;
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2NoZWR1bGVyLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vc3JjL2FuaW1hdGlvbi9zY2hlZHVsZXIudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IjtBQUFBOzs7R0FHRzs7O0FBRUgsMkNBQWdEO0FBQ2hELDRDQUtzQjtBQUN0QixpQ0FLZ0I7QUFDaEIseUNBQXNDO0FBb0J0QyxvQ0FBb0M7QUFDcEMsSUFBSSxzQkFBc0IsR0FBNEIsSUFBSSxDQUFDO0FBRXBELE1BQU0seUJBQXlCLEdBQUcsR0FBcUIsRUFBRTtJQUM5RCxJQUFJLENBQUMsc0JBQXNCLEVBQUUsQ0FBQztRQUM1QixzQkFBc0IsR0FBRyxzQkFBc0IsRUFBRSxDQUFDO0lBQ3BELENBQUM7SUFDRCxPQUFPLHNCQUFzQixDQUFDO0FBQ2hDLENBQUMsQ0FBQztBQUxXLFFBQUEseUJBQXlCLDZCQUtwQztBQUVGLDBEQUEwRDtBQUMxRCxNQUFNLHNCQUFzQixHQUFHLEdBQXFCLEVBQUU7SUFDcEQsTUFBTSxnQkFBZ0IsR0FBRyxJQUFBLGVBQU0sRUFBQyxJQUFJLEdBQUcsRUFBVSxDQUFDLENBQUM7SUFDbkQsTUFBTSxTQUFTLEdBQUcsSUFBQSxlQUFNLEVBQUMsRUFBRSxDQUFDLENBQUM7SUFFN0IseUJBQXlCO0lBQ3pCLElBQUksVUFBVSxHQUFHLENBQUMsQ0FBQztJQUNuQixJQUFJLGFBQWEsR0FBRyxDQUFDLENBQUM7SUFFdEIsTUFBTSxVQUFVLEdBQUcsSUFBSSxHQUFHLEVBQTBCLENBQUM7SUFDckQsTUFBTSxjQUFjLEdBQUcsSUFBSSxHQUFHLEVBQWtCLENBQUMsQ0FBQyx3QkFBd0I7SUFFMUUsSUFBSSxTQUFTLEdBQUcsS0FBSyxDQUFDO0lBQ3RCLElBQUksWUFBWSxHQUFrQixJQUFJLENBQUM7SUFFdkMsTUFBTSxlQUFlLEdBQUcsQ0FBQyxXQUFtQixFQUFFLEVBQUU7UUFDOUMsVUFBVSxFQUFFLENBQUM7UUFFYixJQUFJLFdBQVcsR0FBRyxhQUFhLElBQUksSUFBSSxFQUFFLENBQUM7WUFDeEMsTUFBTSxHQUFHLEdBQUcsVUFBVSxHQUFHLENBQUMsQ0FBQyxXQUFXLEdBQUcsYUFBYSxDQUFDLEdBQUcsSUFBSSxDQUFDLENBQUM7WUFDaEUsU0FBUyxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUM7WUFDaEMsVUFBVSxHQUFHLENBQUMsQ0FBQztZQUNmLGFBQWEsR0FBRyxXQUFXLENBQUM7UUFDOUIsQ0FBQztJQUNILENBQUMsQ0FBQztJQUVGLE1BQU0sYUFBYSxHQUFHLEdBQUcsRUFBRTtRQUN6QixNQUFNLFdBQVcsR0FBRyxXQUFXLENBQUMsR0FBRyxFQUFFLENBQUM7UUFDdEMsZUFBZSxDQUFDLFdBQVcsQ0FBQyxDQUFDO1FBRTdCLCtCQUErQjtRQUMvQixNQUFNLFNBQVMsR0FBRyxJQUFJLEdBQUcsRUFBVSxDQUFDO1FBRXBDLEtBQUssTUFBTSxDQUFDLEVBQUUsRUFBRSxJQUFJLENBQUMsSUFBSSxLQUFLLENBQUMsSUFBSSxDQUFDLFVBQVUsQ0FBQyxPQUFPLEVBQUUsQ0FBQyxFQUFFLENBQUM7WUFDMUQsSUFBSSxDQUFDLElBQUksQ0FBQyxVQUFVLENBQUMsS0FBSyxFQUFFLEVBQUUsQ0FBQztnQkFDN0IsU0FBUyxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUMsQ0FBQztnQkFFbEIsc0VBQXNFO2dCQUN0RSwwREFBMEQ7WUFDNUQsQ0FBQztpQkFBTSxDQUFDO2dCQUNOLGlDQUFpQztnQkFDakMsVUFBVSxDQUFDLE1BQU0sQ0FBQyxFQUFFLENBQUMsQ0FBQztnQkFDdEIsTUFBTSxNQUFNLEdBQUcsY0FBYyxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUMsQ0FBQztnQkFDdEMsSUFBSSxNQUFNLEVBQUUsQ0FBQztvQkFDWCxJQUFBLGtCQUFNLEVBQUMsTUFBTSxDQUFDLENBQUM7b0JBQ2YsY0FBYyxDQUFDLE1BQU0sQ0FBQyxFQUFFLENBQUMsQ0FBQztnQkFDNUIsQ0FBQztZQUNILENBQUM7UUFDSCxDQUFDO1FBRUQsZ0JBQWdCLENBQUMsSUFBSSxDQUFDLFNBQVMsQ0FBQyxDQUFDO1FBRWpDLG1EQUFtRDtRQUNuRCxJQUFJLFNBQVMsQ0FBQyxJQUFJLEdBQUcsQ0FBQyxFQUFFLENBQUM7WUFDdkIsT0FBTyxPQUFPLENBQUMsT0FBTyxFQUFFLENBQUMsQ0FBQyw4QkFBOEI7UUFDMUQsQ0FBQzthQUFNLENBQUM7WUFDTiwyQ0FBMkM7WUFDM0MsU0FBUyxHQUFHLEtBQUssQ0FBQztZQUNsQixZQUFZLEdBQUcsSUFBSSxDQUFDO1lBQ3BCLE9BQU8sT0FBTyxDQUFDLE9BQU8sRUFBRSxDQUFDLENBQUMsMEJBQTBCO1FBQ3RELENBQUM7SUFDSCxDQUFDLENBQUM7SUFFRixNQUFNLGVBQWUsR0FBRyxHQUFHLEVBQUU7UUFDM0IsSUFBSSxDQUFDLFNBQVMsSUFBSSxVQUFVLENBQUMsSUFBSSxHQUFHLENBQUMsRUFBRSxDQUFDO1lBQ3RDLFNBQVMsR0FBRyxJQUFJLENBQUM7WUFDakIsYUFBYSxHQUFHLFdBQVcsQ0FBQyxHQUFHLEVBQUUsQ0FBQztZQUNsQyxVQUFVLEdBQUcsQ0FBQyxDQUFDO1lBRWYsWUFBWSxHQUFHLElBQUEsb0JBQVEsRUFBQztnQkFDdEIsUUFBUSxFQUFFLG9CQUFRLENBQUMsSUFBSTtnQkFDdkIsTUFBTSxFQUFFLElBQUk7Z0JBQ1osT0FBTyxFQUFFLGFBQWE7YUFDdkIsQ0FBQyxDQUFDO1FBQ0wsQ0FBQztJQUNILENBQUMsQ0FBQztJQUVGLE1BQU0sY0FBYyxHQUFHLEdBQUcsRUFBRTtRQUMxQixJQUFJLFNBQVMsSUFBSSxZQUFZLEVBQUUsQ0FBQztZQUM5QixJQUFBLGtCQUFNLEVBQUMsWUFBWSxDQUFDLENBQUM7WUFDckIsU0FBUyxHQUFHLEtBQUssQ0FBQztZQUNsQixZQUFZLEdBQUcsSUFBSSxDQUFDO1FBQ3RCLENBQUM7SUFDSCxDQUFDLENBQUM7SUFFRixNQUFNLFFBQVEsR0FBcUI7UUFDakMsZ0JBQWdCO1FBQ2hCLFNBQVM7UUFFVCxRQUFRLEVBQUUsQ0FBSSxTQUF1QixFQUFVLEVBQUU7WUFDL0MsVUFBVSxDQUFDLEdBQUcsQ0FBQyxTQUFTLENBQUMsRUFBRSxFQUFFLFNBQVMsQ0FBQyxDQUFDO1lBRXhDLCtDQUErQztZQUMvQyxlQUFlLEVBQUUsQ0FBQztZQUVsQiwwQ0FBMEM7WUFDMUMsU0FBUyxDQUFDLFVBQVUsQ0FBQyxHQUFHLEVBQUU7Z0JBQ3hCLFVBQVUsQ0FBQyxNQUFNLENBQUMsU0FBUyxDQUFDLEVBQUUsQ0FBQyxDQUFDO2dCQUNoQyxNQUFNLE1BQU0sR0FBRyxjQUFjLENBQUMsR0FBRyxDQUFDLFNBQVMsQ0FBQyxFQUFFLENBQUMsQ0FBQztnQkFDaEQsSUFBSSxNQUFNLEVBQUUsQ0FBQztvQkFDWCxJQUFBLGtCQUFNLEVBQUMsTUFBTSxDQUFDLENBQUM7b0JBQ2YsY0FBYyxDQUFDLE1BQU0sQ0FBQyxTQUFTLENBQUMsRUFBRSxDQUFDLENBQUM7Z0JBQ3RDLENBQUM7Z0JBRUQsMkJBQTJCO2dCQUMzQixNQUFNLE9BQU8sR0FBRyxnQkFBZ0IsQ0FBQyxLQUFLLEVBQUUsQ0FBQztnQkFDekMsTUFBTSxPQUFPLEdBQUcsSUFBSSxHQUFHLENBQUMsT0FBTyxDQUFDLENBQUM7Z0JBQ2pDLE9BQU8sQ0FBQyxNQUFNLENBQUMsU0FBUyxDQUFDLEVBQUUsQ0FBQyxDQUFDO2dCQUM3QixnQkFBZ0IsQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDLENBQUM7Z0JBRS9CLHlDQUF5QztnQkFDekMsSUFBSSxPQUFPLENBQUMsSUFBSSxLQUFLLENBQUMsRUFBRSxDQUFDO29CQUN2QixjQUFjLEVBQUUsQ0FBQztnQkFDbkIsQ0FBQztZQUNILENBQUMsQ0FBQyxDQUFDO1lBRUgsT0FBTyxTQUFTLENBQUMsRUFBRSxDQUFDO1FBQ3RCLENBQUM7UUFFRCxVQUFVLEVBQUUsQ0FBQyxXQUFtQixFQUFXLEVBQUU7WUFDM0MsTUFBTSxTQUFTLEdBQUcsVUFBVSxDQUFDLEdBQUcsQ0FBQyxXQUFXLENBQUMsQ0FBQztZQUM5QyxJQUFJLFNBQVMsRUFBRSxDQUFDO2dCQUNkLFNBQVMsQ0FBQyxJQUFJLEVBQUUsQ0FBQztnQkFDakIsVUFBVSxDQUFDLE1BQU0sQ0FBQyxXQUFXLENBQUMsQ0FBQztnQkFFL0IsTUFBTSxNQUFNLEdBQUcsY0FBYyxDQUFDLEdBQUcsQ0FBQyxXQUFXLENBQUMsQ0FBQztnQkFDL0MsSUFBSSxNQUFNLEVBQUUsQ0FBQztvQkFDWCxJQUFBLGtCQUFNLEVBQUMsTUFBTSxDQUFDLENBQUM7b0JBQ2YsY0FBYyxDQUFDLE1BQU0sQ0FBQyxXQUFXLENBQUMsQ0FBQztnQkFDckMsQ0FBQztnQkFFRCwyQkFBMkI7Z0JBQzNCLE1BQU0sT0FBTyxHQUFHLGdCQUFnQixDQUFDLEtBQUssRUFBRSxDQUFDO2dCQUN6QyxNQUFNLE9BQU8sR0FBRyxJQUFJLEdBQUcsQ0FBQyxPQUFPLENBQUMsQ0FBQztnQkFDakMsT0FBTyxDQUFDLE1BQU0sQ0FBQyxXQUFXLENBQUMsQ0FBQztnQkFDNUIsZ0JBQWdCLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxDQUFDO2dCQUUvQixPQUFPLElBQUksQ0FBQztZQUNkLENBQUM7WUFDRCxPQUFPLEtBQUssQ0FBQztRQUNmLENBQUM7UUFFRCxLQUFLLEVBQUUsR0FBRyxFQUFFO1lBQ1YsS0FBSyxNQUFNLFNBQVMsSUFBSSxLQUFLLENBQUMsSUFBSSxDQUFDLFVBQVUsQ0FBQyxNQUFNLEVBQUUsQ0FBQyxFQUFFLENBQUM7Z0JBQ3hELFNBQVMsQ0FBQyxLQUFLLEVBQUUsQ0FBQztZQUNwQixDQUFDO1lBQ0QsY0FBYyxFQUFFLENBQUM7UUFDbkIsQ0FBQztRQUVELE1BQU0sRUFBRSxHQUFHLEVBQUU7WUFDWCxLQUFLLE1BQU0sU0FBUyxJQUFJLEtBQUssQ0FBQyxJQUFJLENBQUMsVUFBVSxDQUFDLE1BQU0sRUFBRSxDQUFDLEVBQUUsQ0FBQztnQkFDeEQsU0FBUyxDQUFDLE1BQU0sRUFBRSxDQUFDO1lBQ3JCLENBQUM7WUFDRCxlQUFlLEVBQUUsQ0FBQztRQUNwQixDQUFDO1FBRUQsS0FBSyxFQUFFLEdBQUcsRUFBRTtZQUNWLEtBQUssTUFBTSxTQUFTLElBQUksS0FBSyxDQUFDLElBQUksQ0FBQyxVQUFVLENBQUMsTUFBTSxFQUFFLENBQUMsRUFBRSxDQUFDO2dCQUN4RCxTQUFTLENBQUMsSUFBSSxFQUFFLENBQUM7WUFDbkIsQ0FBQztZQUVELEtBQUssTUFBTSxNQUFNLElBQUksS0FBSyxDQUFDLElBQUksQ0FBQyxjQUFjLENBQUMsTUFBTSxFQUFFLENBQUMsRUFBRSxDQUFDO2dCQUN6RCxJQUFBLGtCQUFNLEVBQUMsTUFBTSxDQUFDLENBQUM7WUFDakIsQ0FBQztZQUVELFVBQVUsQ0FBQyxLQUFLLEVBQUUsQ0FBQztZQUNuQixjQUFjLENBQUMsS0FBSyxFQUFFLENBQUM7WUFDdkIsZ0JBQWdCLENBQUMsSUFBSSxDQUFDLElBQUksR0FBRyxFQUFFLENBQUMsQ0FBQztZQUNqQyxjQUFjLEVBQUUsQ0FBQztRQUNuQixDQUFDO0tBQ0YsQ0FBQztJQUVGLE9BQU8sUUFBUSxDQUFDO0FBQ2xCLENBQUMsQ0FBQztBQUVGLDBFQUEwRTtBQUNuRSxNQUFNLGtCQUFrQixHQUFHLENBQ2hDLElBQU8sRUFDUCxFQUFLLEVBQ0wsUUFBZ0IsRUFDaEIsWUFBNkIsRUFDN0IsTUFBdUIsRUFDQSxFQUFFO0lBQ3pCLE1BQU0sYUFBYSxHQUFHLElBQUEsZ0JBQVMsRUFBQyxJQUFJLEVBQUUsRUFBRSxFQUFFLFFBQVEsRUFBRSxZQUFZLEVBQUUsTUFBTSxDQUFDLENBQUM7SUFDMUUsTUFBTSxpQkFBaUIsR0FBRyxJQUFBLGVBQU0sRUFBQyxLQUFLLENBQUMsQ0FBQztJQUV4QyxJQUFJLE1BQU0sR0FBa0IsSUFBSSxDQUFDO0lBRWpDLE1BQU0sUUFBUSxHQUEwQjtRQUN0QyxHQUFHLGFBQWE7UUFDaEIsTUFBTTtRQUNOLFdBQVcsRUFBRSxpQkFBaUI7UUFFOUIsS0FBSyxFQUFFLEdBQUcsRUFBRTtZQUNWLGtDQUFrQztZQUNsQyxNQUFNLE9BQU8sR0FBRyxJQUFBLGlDQUF5QixHQUFFLENBQUM7WUFDNUMsT0FBTyxDQUFDLFFBQVEsQ0FBQyxhQUFhLENBQUMsQ0FBQztZQUNoQyxpQkFBaUIsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLENBQUM7WUFFN0IsMkJBQTJCO1lBQzNCLGFBQWEsQ0FBQyxLQUFLLEVBQUUsQ0FBQztRQUN4QixDQUFDO1FBRUQsSUFBSSxFQUFFLEdBQUcsRUFBRTtZQUNULG9DQUFvQztZQUNwQyxNQUFNLE9BQU8sR0FBRyxJQUFBLGlDQUF5QixHQUFFLENBQUM7WUFDNUMsT0FBTyxDQUFDLFVBQVUsQ0FBQyxhQUFhLENBQUMsRUFBRSxDQUFDLENBQUM7WUFDckMsaUJBQWlCLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFDO1lBRTlCLDBCQUEwQjtZQUMxQixhQUFhLENBQUMsSUFBSSxFQUFFLENBQUM7UUFDdkIsQ0FBQztRQUVELEtBQUssRUFBRSxHQUFHLEVBQUU7WUFDVixhQUFhLENBQUMsS0FBSyxFQUFFLENBQUM7UUFDeEIsQ0FBQztRQUVELE1BQU0sRUFBRSxHQUFHLEVBQUU7WUFDWCxhQUFhLENBQUMsTUFBTSxFQUFFLENBQUM7UUFDekIsQ0FBQztLQUNGLENBQUM7SUFFRixPQUFPLFFBQVEsQ0FBQztBQUNsQixDQUFDLENBQUM7QUEvQ1csUUFBQSxrQkFBa0Isc0JBK0M3QjtBQUVGLG9GQUFvRjtBQUM3RSxNQUFNLE9BQU8sR0FBRyxDQUNyQixJQUFPLEVBQ1AsRUFBSyxFQUNMLFFBQWdCLEVBQ2hCLFlBQTZCLEVBQzdCLE1BQXVCLEVBQ0EsRUFBRTtJQUN6QixPQUFPLElBQUEsMEJBQWtCLEVBQUMsSUFBSSxFQUFFLEVBQUUsRUFBRSxRQUFRLEVBQUUsWUFBWSxFQUFFLE1BQU0sQ0FBQyxDQUFDO0FBQ3RFLENBQUMsQ0FBQztBQVJXLFFBQUEsT0FBTyxXQVFsQjtBQUVGLDBDQUEwQztBQUNuQyxNQUFNLGlCQUFpQixHQUFHLEdBRy9CLEVBQUU7SUFDRixNQUFNLFlBQVksR0FBRyxJQUFBLG1CQUFRLEdBQUUsQ0FBQztJQUNoQyxJQUFJLFlBQVksR0FBRyxLQUFLLENBQUM7SUFFekIsTUFBTSxRQUFRLEdBQUcsR0FBRyxFQUFFO1FBQ3BCLElBQUksQ0FBQyxZQUFZLEVBQUUsQ0FBQztZQUNsQixNQUFNLE9BQU8sR0FBRyxJQUFBLGlDQUF5QixHQUFFLENBQUM7WUFDNUMsd0RBQXdEO1lBQ3hELE1BQU0sU0FBUyxHQUFHLElBQUEsZ0JBQVMsRUFBQyxDQUFDLEVBQUUsQ0FBQyxFQUFFLFlBQVksQ0FBQyxRQUFRLEVBQUUsQ0FBQyxFQUFFLEVBQUUsRUFBRSxFQUFFLENBQUMsRUFBRSxFQUFFLENBQUMsQ0FBQyxDQUFDLENBQUM7WUFDM0UsT0FBTyxDQUFDLFFBQVEsQ0FBQyxTQUFTLENBQUMsQ0FBQztZQUM1QixZQUFZLEdBQUcsSUFBSSxDQUFDO1FBQ3RCLENBQUM7SUFDSCxDQUFDLENBQUM7SUFFRixNQUFNLFVBQVUsR0FBRyxHQUFHLEVBQUU7UUFDdEIsSUFBSSxZQUFZLEVBQUUsQ0FBQztZQUNqQixtREFBbUQ7WUFDbkQsWUFBWSxHQUFHLEtBQUssQ0FBQztRQUN2QixDQUFDO0lBQ0gsQ0FBQyxDQUFDO0lBRUYsT0FBTztRQUNMLEdBQUcsWUFBWTtRQUNmLFFBQVE7UUFDUixVQUFVO1FBRVYsS0FBSyxFQUFFLEdBQUcsRUFBRTtZQUNWLFFBQVEsRUFBRSxDQUFDO1lBQ1gsWUFBWSxDQUFDLEtBQUssRUFBRSxDQUFDO1FBQ3ZCLENBQUM7UUFFRCxJQUFJLEVBQUUsR0FBRyxFQUFFO1lBQ1QsVUFBVSxFQUFFLENBQUM7WUFDYixZQUFZLENBQUMsSUFBSSxFQUFFLENBQUM7UUFDdEIsQ0FBQztLQUNGLENBQUM7QUFDSixDQUFDLENBQUM7QUF2Q1csUUFBQSxpQkFBaUIscUJBdUM1QjtBQUVGLG1DQUFtQztBQUM1QixNQUFNLGlCQUFpQixHQUFHLEdBQUcsRUFBRTtJQUNwQyxNQUFNLE9BQU8sR0FBRyxJQUFBLGlDQUF5QixHQUFFLENBQUM7SUFFNUMsT0FBTztRQUNMLFdBQVcsRUFBRSxPQUFPLENBQUMsZ0JBQWdCLENBQUMsS0FBSyxFQUFFLENBQUMsSUFBSTtRQUNsRCxTQUFTLEVBQUUsT0FBTyxDQUFDLFNBQVMsQ0FBQyxLQUFLLEVBQUU7UUFDcEMsU0FBUyxFQUFFLElBQUEsOEJBQWtCLEdBQUUsQ0FBQyxLQUFLLENBQUMsS0FBSyxFQUFFO0tBQzlDLENBQUM7QUFDSixDQUFDLENBQUM7QUFSVyxRQUFBLGlCQUFpQixxQkFRNUI7QUFFRixrQkFBa0I7QUFDWCxNQUFNLGVBQWUsR0FBRyxHQUFHLEVBQUU7SUFDbEMsTUFBTSxPQUFPLEdBQUcsSUFBQSxpQ0FBeUIsR0FBRSxDQUFDO0lBQzVDLE1BQU0sS0FBSyxHQUFHLElBQUEseUJBQWlCLEdBQUUsQ0FBQztJQUVsQyxPQUFPLENBQUMsS0FBSyxDQUFDLHNCQUFzQixDQUFDLENBQUM7SUFDdEMsT0FBTyxDQUFDLEdBQUcsQ0FBQyxvQkFBb0IsRUFBRSxLQUFLLENBQUMsV0FBVyxDQUFDLENBQUM7SUFDckQsT0FBTyxDQUFDLEdBQUcsQ0FBQyxhQUFhLEVBQUUsS0FBSyxDQUFDLFNBQVMsRUFBRSxLQUFLLENBQUMsQ0FBQztJQUNuRCxPQUFPLENBQUMsR0FBRyxDQUFDLGtCQUFrQixFQUFFLEtBQUssQ0FBQyxTQUFTLENBQUMsQ0FBQztJQUNqRCxPQUFPLENBQUMsR0FBRyxDQUNULHVCQUF1QixFQUN2QixLQUFLLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxnQkFBZ0IsQ0FBQyxLQUFLLEVBQUUsQ0FBQyxDQUM3QyxDQUFDO0lBQ0YsT0FBTyxDQUFDLFFBQVEsRUFBRSxDQUFDO0FBQ3JCLENBQUMsQ0FBQztBQWJXLFFBQUEsZUFBZSxtQkFhMUI7QUFFRixpQ0FBaUM7QUFDMUIsTUFBTSxpQkFBaUIsR0FBRyxDQUFDLFdBQW1CLElBQUksRUFBRSxFQUFFO0lBQzNELE1BQU0sT0FBTyxHQUFHLElBQUEsaUNBQXlCLEdBQUUsQ0FBQztJQUM1QyxNQUFNLFNBQVMsR0FBRyxXQUFXLENBQUMsR0FBRyxFQUFFLENBQUM7SUFDcEMsTUFBTSxPQUFPLEdBQXdELEVBQUUsQ0FBQztJQUV4RSxNQUFNLGNBQWMsR0FBRyxXQUFXLENBQUMsR0FBRyxFQUFFO1FBQ3RDLE1BQU0sV0FBVyxHQUFHLFdBQVcsQ0FBQyxHQUFHLEVBQUUsQ0FBQztRQUN0QyxPQUFPLENBQUMsSUFBSSxDQUFDO1lBQ1gsSUFBSSxFQUFFLFdBQVcsR0FBRyxTQUFTO1lBQzdCLEtBQUssRUFBRSxPQUFPLENBQUMsZ0JBQWdCLENBQUMsS0FBSyxFQUFFLENBQUMsSUFBSTtZQUM1QyxHQUFHLEVBQUUsT0FBTyxDQUFDLFNBQVMsQ0FBQyxLQUFLLEVBQUU7U0FDL0IsQ0FBQyxDQUFDO0lBQ0wsQ0FBQyxFQUFFLEdBQUcsQ0FBQyxDQUFDO0lBRVIsVUFBVSxDQUFDLEdBQUcsRUFBRTtRQUNkLGFBQWEsQ0FBQyxjQUFjLENBQUMsQ0FBQztRQUU5QixPQUFPLENBQUMsS0FBSyxDQUFDLCtCQUErQixDQUFDLENBQUM7UUFDL0MsT0FBTyxDQUFDLEtBQUssQ0FBQyxPQUFPLENBQUMsQ0FBQztRQUV2QixNQUFNLE1BQU0sR0FBRyxPQUFPLENBQUMsTUFBTSxDQUFDLENBQUMsR0FBRyxFQUFFLENBQUMsRUFBRSxFQUFFLENBQUMsR0FBRyxHQUFHLENBQUMsQ0FBQyxHQUFHLEVBQUUsQ0FBQyxDQUFDLEdBQUcsT0FBTyxDQUFDLE1BQU0sQ0FBQztRQUMzRSxNQUFNLGFBQWEsR0FBRyxJQUFJLENBQUMsR0FBRyxDQUFDLEdBQUcsT0FBTyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsRUFBRSxFQUFFLENBQUMsQ0FBQyxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUM7UUFFL0QsT0FBTyxDQUFDLEdBQUcsQ0FBQyxjQUFjLEVBQUUsTUFBTSxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO1FBQy9DLE9BQU8sQ0FBQyxHQUFHLENBQUMsNEJBQTRCLEVBQUUsYUFBYSxDQUFDLENBQUM7UUFDekQsT0FBTyxDQUFDLFFBQVEsRUFBRSxDQUFDO0lBQ3JCLENBQUMsRUFBRSxRQUFRLENBQUMsQ0FBQztJQUViLE9BQU8sR0FBRyxFQUFFLENBQUMsYUFBYSxDQUFDLGNBQWMsQ0FBQyxDQUFDO0FBQzdDLENBQUMsQ0FBQztBQTdCVyxRQUFBLGlCQUFpQixxQkE2QjVCIn0=