Complete and Professional Implementation of the EARCP Architecture
Ensemble Auto-Régulé par Cohérence et Performance
A Python library for adaptive ensemble learning with theoretical guarantees
from earcp import EARCP
# Create ensemble
ensemble = EARCP(experts=[model1, model2, model3])
# Use it
for x, y in data:
pred, expert_preds = ensemble.predict(x)
ensemble.update(expert_preds, y)That's it! You just created an adaptive ensemble with O(√T log M) theoretical guarantees.
pip install earcpgit clone -b earcp-lib https://github.com/Volgat/earcp.git
cd earcp
pip install -e .
# With all dependencies
pip install -e ".[full]"# PyTorch support
pip install earcp[torch]
# scikit-learn support
pip install earcp[sklearn]
# TensorFlow/Keras support
pip install earcp[tensorflow]
# Full installation
pip install earcp[full]| Feature | EARCP | Classical Ensembles |
|---|---|---|
| Adaptive | ✅ Online weight updates | ❌ Fixed or offline weights |
| Theory | ✅ Proven O(√T log M) regret | |
| Diversity | ✅ Coherence maintains diversity | ❌ Can converge to one |
| Robust | ✅ Minimum weight guaranteed | |
| Flexible | ✅ Any ML framework | |
| Real-time | ✅ Streaming data |
from earcp import EARCP
# One-line initialization
ensemble = EARCP(experts=my_models, beta=0.7, eta_s=5.0)
# Two main methods
prediction, expert_predictions = ensemble.predict(input)
metrics = ensemble.update(expert_predictions, target)
# Complete diagnostics
diagnostics = ensemble.get_diagnostics()from earcp.utils.wrappers import SklearnWrapper, TorchWrapper, KerasWrapper
# Scikit-learn
sklearn_experts = [SklearnWrapper(model) for model in sklearn_models]
# PyTorch
torch_experts = [TorchWrapper(model) for model in torch_models]
# TensorFlow/Keras
keras_experts = [KerasWrapper(model) for model in keras_models]
# Mix them all!
mixed_experts = sklearn_experts + torch_experts + keras_experts
ensemble = EARCP(experts=mixed_experts)from earcp import get_preset_config
# Predefined presets
configs = {
'performance_focused': get_preset_config('performance_focused'), # β=0.95
'diversity_focused': get_preset_config('diversity_focused'), # β=0.5
'balanced': get_preset_config('balanced'), # β=0.7 (recommended)
'conservative': get_preset_config('conservative'), # Slow adaptation
'aggressive': get_preset_config('aggressive'), # Fast adaptation
'robust': get_preset_config('robust'), # Noise resistant
}
ensemble = EARCP(experts=experts, config=configs['balanced'])from earcp.utils.visualization import plot_diagnostics, plot_weights, plot_regret
diagnostics = ensemble.get_diagnostics()
# Complete dashboard (6 plots)
plot_diagnostics(diagnostics, save_path='analysis.png')
# Individual plots
plot_weights(diagnostics['weights_history'])
plot_regret(expert_losses, ensemble_loss)Automatically generates:
- Weight evolution over time
- Performance scores tracking
- Coherence scores tracking
- Final weight distribution
- Cumulative losses comparison
- Regret analysis
from earcp.utils.metrics import (
compute_regret,
compute_diversity,
evaluate_ensemble,
theoretical_regret_bound
)
# Regret vs best expert
regret_metrics = compute_regret(expert_losses, ensemble_loss)
print(f"Regret: {regret_metrics['regret']:.4f}")
print(f"Best expert: {regret_metrics['best_expert']}")
# Ensemble diversity
diversity = compute_diversity(weights_history)
print(f"Mean entropy: {diversity['mean_entropy']:.4f}")
print(f"Effective experts: {diversity['mean_effective_experts']:.1f}")
# Theoretical bound
bound = theoretical_regret_bound(T=1000, M=5, beta=0.7)
print(f"Theoretical bound: {bound:.4f}")Surgical Path Planning
Combine multiple path planning algorithms for safer robotic surgery:
from earcp import EARCP
# Different path planning strategies
class RRTPlanner:
"""Rapidly-exploring Random Tree planner."""
def predict(self, surgical_state):
return self.compute_rrt_path(surgical_state)
class APFPlanner:
"""Artificial Potential Field planner."""
def predict(self, surgical_state):
return self.compute_apf_path(surgical_state)
class MLPlanner:
"""Machine learning-based planner."""
def predict(self, surgical_state):
return self.neural_network(surgical_state)
# Create ensemble for robust path planning
planners = [RRTPlanner(), APFPlanner(), MLPlanner()]
ensemble = EARCP(experts=planners, beta=0.8)
# Real-time adaptation during surgery
for surgical_state in surgery_stream:
# Get ensemble path recommendation
planned_path, expert_paths = ensemble.predict(surgical_state)
# Execute path segment
result = robot.execute_path_segment(planned_path)
# Update based on execution success
success_metric = evaluate_execution(result)
ensemble.update(expert_paths, success_metric)Patient Monitoring
Combine vital sign prediction models:
# Different vital sign predictors
experts = [
LSTM_VitalPredictor(), # Deep learning
KalmanFilter(), # State-space model
ARIMA_Predictor(), # Time series
PhysiologicalModel() # Physics-based
]
ensemble = EARCP(experts=experts, beta=0.7)
# Continuous monitoring
for vital_signs in patient_monitor:
# Predict next values
prediction, expert_preds = ensemble.predict(vital_signs)
# Wait for actual reading
actual = wait_for_next_reading()
# Update predictors
ensemble.update(expert_preds, actual)
# Alert if anomaly
if anomaly_detected(prediction, actual):
trigger_alert()Multi-Modal Object Detection
Combine RGB, depth, and thermal detectors:
from earcp import EARCP
from earcp.utils.wrappers import TorchWrapper
# Different sensor modalities
experts = [
TorchWrapper(YOLOv8_RGB()), # RGB detector
TorchWrapper(DepthNet()), # Depth-based
TorchWrapper(ThermalDetector()), # Thermal imaging
TorchWrapper(FusionNet()) # Multi-modal fusion
]
ensemble = EARCP(experts=experts, beta=0.75)
# Adaptive detection system
for frame in video_stream:
# Get multi-modal input
rgb, depth, thermal = preprocess(frame)
# Ensemble detection
detections, expert_detections = ensemble.predict({
'rgb': rgb,
'depth': depth,
'thermal': thermal
})
# Ground truth from user correction or tracking
ground_truth = get_ground_truth(detections)
# Update weights based on accuracy
ensemble.update(expert_detections, ground_truth)Medical Image Segmentation
Ensemble of segmentation models for robust tumor detection:
# Medical image segmentation models
experts = [
TorchWrapper(UNet()), # U-Net
TorchWrapper(ResUNet()), # Residual U-Net
TorchWrapper(AttentionUNet()), # Attention U-Net
TorchWrapper(TransUNet()), # Transformer U-Net
]
ensemble = EARCP(experts=experts, beta=0.8)
# Process medical scans
for scan, mask in medical_dataset:
# Ensemble segmentation
seg_pred, expert_segs = ensemble.predict(scan)
# Radiologist verification/correction
verified_mask = radiologist_review(seg_pred, scan)
# Update based on expert feedback
ensemble.update(expert_segs, verified_mask)Self-Driving Decision Making
Combine multiple driving policies:
# Autonomous driving policies
experts = [
ConservativeDriver(), # Safety-first policy
AggressiveDriver(), # Efficiency-focused
LearningDriver(), # RL-trained agent
RuleBasedDriver() # Traditional FSM
]
ensemble = EARCP(experts=experts, beta=0.7)
# Adaptive driving
for sensor_data in driving_stream:
# Get action recommendations
action, expert_actions = ensemble.predict(sensor_data)
# Execute action
state_change = vehicle.execute(action)
# Evaluate action quality
reward = compute_reward(state_change)
# Update policy weights
ensemble.update(expert_actions, reward)Drone Navigation
Multi-strategy navigation for varying conditions:
# Navigation strategies
experts = [
GPS_Navigator(), # GPS-based
SLAM_Navigator(), # Visual SLAM
InertialNavigator(), # IMU-based
HybridNavigator() # Sensor fusion
]
ensemble = EARCP(experts=experts, beta=0.75)
# Weather-adaptive navigation
for flight_state in mission:
# Get navigation commands
command, expert_commands = ensemble.predict(flight_state)
# Execute and observe
actual_position = drone.execute_and_localize(command)
# Update based on localization accuracy
position_error = compute_error(actual_position, command)
ensemble.update(expert_commands, -position_error)Multi-Model Text Generation
Ensemble LLMs for robust generation:
from earcp import EARCP
from earcp.utils.wrappers import CallableWrapper
# Multiple language models
experts = [
CallableWrapper(gpt4_generate, name='GPT-4'),
CallableWrapper(claude_generate, name='Claude'),
CallableWrapper(llama_generate, name='Llama'),
CallableWrapper(gemini_generate, name='Gemini')
]
ensemble = EARCP(experts=experts, beta=0.7)
# Adaptive generation with user feedback
for prompt in user_inputs:
# Generate from ensemble
response, expert_responses = ensemble.predict(prompt)
# Display to user
display(response)
# Get user rating
user_rating = get_user_feedback()
# Update based on satisfaction
ensemble.update(expert_responses, user_rating)Named Entity Recognition
Combine NER models for robust extraction:
# NER models
experts = [
SpaCyNER(), # spaCy
TransformerNER(), # BERT-based
BiLSTM_CRF_NER(), # Traditional deep learning
RuleBasedNER() # Pattern matching
]
ensemble = EARCP(experts=experts, beta=0.8)
# Process documents
for document in document_stream:
# Extract entities
entities, expert_entities = ensemble.predict(document)
# Human verification
verified_entities = human_annotator(entities, document)
# Update with corrections
ensemble.update(expert_entities, verified_entities)Multi-Strategy Trading System
# Trading strategies
experts = [
MomentumStrategy(lookback=20),
MeanReversionStrategy(lookback=50),
MachineLearningStrategy(),
SentimentAnalysisStrategy(),
TechnicalAnalysisStrategy()
]
ensemble = EARCP(experts=experts, beta=0.75)
# Live trading
portfolio_value = 100000
for market_state in market_stream:
# Get trading signals
signal, expert_signals = ensemble.predict(market_state)
# Execute trades
trades = execute_trades(signal)
# Calculate realized P&L
pnl = calculate_pnl(trades, market_state)
portfolio_value += pnl
# Update strategies (negative loss = positive return)
ensemble.update(expert_signals, np.array([pnl]))
# Risk management
if portfolio_value < 95000:
ensemble.weighting.set_beta(0.5) # More conservativeEquipment Failure Prediction
# Failure prediction models
experts = [
VibrationAnalyzer(), # Frequency domain analysis
TemperatureModel(), # Thermal monitoring
AcousticAnalyzer(), # Sound pattern recognition
MLPredictor(), # Data-driven ML
PhysicsModel() # First-principles model
]
ensemble = EARCP(experts=experts, beta=0.8)
# Real-time monitoring
for sensor_data in equipment_stream:
# Predict time to failure
ttf_pred, expert_ttf = ensemble.predict(sensor_data)
# Schedule maintenance if needed
if ttf_pred < threshold:
schedule_maintenance()
# Update when actual failure occurs or maintenance done
if maintenance_event:
actual_ttf = time_to_event
ensemble.update(expert_ttf, actual_ttf)Multi-Model Weather Ensemble
# Weather prediction models
experts = [
NumericalWeatherModel(), # Physics-based NWP
MLWeatherModel(), # Deep learning
EnsembleWeatherModel(), # Traditional ensemble
StatisticalModel(), # Statistical post-processing
]
ensemble = EARCP(experts=experts, beta=0.7)
# Adaptive forecasting
for current_conditions in weather_stream:
# 24h forecast
forecast, expert_forecasts = ensemble.predict(current_conditions)
# Wait 24 hours
time.sleep(86400)
# Observe actual weather
actual_weather = observe_weather()
# Update based on forecast accuracy
ensemble.update(expert_forecasts, actual_weather)Intrusion Detection System
# Security detection models
experts = [
SignatureBasedDetector(), # Known attack patterns
AnomalyDetector(), # Statistical anomaly
MLDetector(), # ML-based classification
BehavioralAnalyzer(), # User behavior analysis
NetworkAnalyzer() # Network flow analysis
]
ensemble = EARCP(experts=experts, beta=0.8)
# Real-time threat detection
for network_packet in traffic_stream:
# Threat assessment
threat_level, expert_threats = ensemble.predict(network_packet)
# Take action if threat detected
if threat_level > threshold:
block_traffic(network_packet)
# Update with security analyst feedback
analyst_verdict = security_analyst_review(network_packet)
ensemble.update(expert_threats, analyst_verdict)Smart Grid Load Forecasting
# Load forecasting models
experts = [
ARIMAForecaster(), # Time series
LSTMForecaster(), # Deep learning
WeatherDrivenModel(), # Weather-aware
EventAwareModel(), # Special events
EnsembleForecaster() # Traditional ensemble
]
ensemble = EARCP(experts=experts, beta=0.75)
# Dynamic load prediction
for grid_state in grid_stream:
# Forecast next hour load
load_forecast, expert_forecasts = ensemble.predict(grid_state)
# Optimize generation
optimize_generation(load_forecast)
# Observe actual load
actual_load = measure_load(delay=3600)
# Update forecasters
ensemble.update(expert_forecasts, actual_load)Treatment Recommendation System
# Treatment recommendation models
experts = [
ClinicalGuidelineModel(), # Evidence-based guidelines
MLRecommender(), # Data-driven ML
GeneticModel(), # Genomic analysis
OutcomePredictor(), # Historical outcomes
PhysicianExperience() # Expert system
]
ensemble = EARCP(experts=experts, beta=0.8)
# Personalized medicine
for patient in patient_cohort:
# Get treatment recommendations
treatment, expert_treatments = ensemble.predict(patient.data)
# Physician selects final treatment
final_treatment = physician_decision(treatment, patient)
# Follow up after treatment
outcome = patient.followup(weeks=12)
# Update based on treatment success
ensemble.update(expert_treatments, outcome.success_score)| Document | Description | Time |
|---|---|---|
| README.md | Main documentation | 5 min |
| QUICKSTART.md | Quick start guide | 5 min |
| USAGE.md | Complete documentation | 30 min |
| API_REFERENCE.md | API reference | - |
python examples/basic_usage.pyDemonstrates:
- Creating custom experts
- Online learning loop
- Results analysis
python examples/sklearn_integration.pyDemonstrates:
- Integration with 5 sklearn models
- Multi-class classification
- Performance evaluation
python examples/pytorch_example.pyDemonstrates:
- Ensemble of PyTorch models
- GPU acceleration
- Model checkpointing
python examples/timeseries_forecasting.pyDemonstrates:
- Multiple forecasting strategies
- Regime change adaptation
- Visualization
python examples/rl_bandits.pyDemonstrates:
- Multi-armed bandit problem
- Different RL agents
- Regret analysis
python examples/medical_segmentation.pyDemonstrates:
- Medical image segmentation
- Ensemble of U-Net variants
- Uncertainty quantification
earcp/
├── core/ # Core modules
│ ├── performance_tracker.py # Performance tracking (exp. smoothing)
│ ├── coherence_metrics.py # Inter-expert coherence computation
│ └── ensemble_weighting.py # Adaptive weight computation
│
├── models/
│ └── earcp_model.py # Main EARCP class
│
├── utils/
│ ├── visualization.py # 6 visualization functions
│ ├── metrics.py # Regret, diversity, evaluation
│ └── wrappers.py # 4 ML framework wrappers
│
├── config.py # Configuration + 6 presets
└── __init__.py # Package initialization
- Exponential smoothing of expert losses
- Cumulative loss tracking
- History management
- Pairwise agreement computation
- Coherence matrix calculation
- Multiple coherence functions
- Exponential weighting mechanism
- Weight floor constraints
- Beta-based signal fusion
# Run all tests
python -m pytest tests/
# Run specific test
python tests/test_basic.py
# With coverage
pytest --cov=earcp tests/tests/
├── test_basic.py # Basic functionality (7 tests)
├── test_integration.py # Framework integration (5 tests)
├── test_metrics.py # Metrics computation (6 tests)
├── test_visualization.py # Plotting functions (4 tests)
└── test_advanced.py # Advanced features (8 tests)
Total: 30 tests
Coverage: 95%+
# .github/workflows/test.yml
name: Tests
on: [push, pull_request]
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Install dependencies
run: pip install -e ".[full]"
- name: Run tests
run: pytest --cov=earcp tests/- Regression: Combine linear, tree-based, and neural models
- Classification: Ensemble CNNs, SVMs, random forests
- Time Series: Combine ARIMA, LSTM, Prophet
- Policy Ensemble: DQN, PPO, A3C agents
- Value Ensembles: Q-learning variants
- Multi-Arm Bandits: Explore/exploit strategies
- Object Detection: YOLOv8, Faster R-CNN, RetinaNet
- Segmentation: U-Net, DeepLab, Mask R-CNN
- Classification: ResNet, VGG, EfficientNet
- Text Generation: GPT, Claude, Llama ensembles
- Classification: BERT, RoBERTa, DistilBERT
- NER: spaCy, Transformers, BiLSTM-CRF
- Diagnosis: Combine multiple diagnostic models
- Treatment: Personalized treatment selection
- Prognosis: Outcome prediction ensembles
- Strategies: Momentum, mean reversion, ML strategies
- Risk: VaR, CVaR, stress testing models
- Forecasting: Technical, fundamental, sentiment
- Navigation: SLAM, GPS, inertial navigation
- Planning: RRT, APF, learning-based planners
- Manipulation: Force, vision, tactile control
- Predictive Maintenance: Failure prediction
- Quality Control: Defect detection
- Process Optimization: Parameter tuning
import numpy as np
from earcp import EARCPConfig
def weighted_mse_loss(y_pred, y_true, weights=None):
"""
Weighted MSE loss for imbalanced data.
Must return value in [0, 1].
"""
if weights is None:
weights = np.ones_like(y_true)
mse = np.average((y_pred - y_true) ** 2, weights=weights)
# Normalize with tanh
return np.tanh(mse)
config = EARCPConfig(loss_fn=weighted_mse_loss)
ensemble = EARCP(experts=experts, config=config)def semantic_coherence(pred_i, pred_j):
"""
Coherence based on semantic similarity.
For NLP applications with embeddings.
"""
# Cosine similarity
dot_product = np.dot(pred_i.flatten(), pred_j.flatten())
norm_i = np.linalg.norm(pred_i)
norm_j = np.linalg.norm(pred_j)
similarity = dot_product / (norm_i * norm_j + 1e-10)
# Map [-1, 1] to [0, 1]
return (similarity + 1) / 2
config = EARCPConfig(coherence_fn=semantic_coherence)
ensemble = EARCP(experts=experts, config=config)# Adapt beta based on environment stability
for t in range(T):
# Measure environment stability
stability = measure_stability(recent_losses)
# Adjust beta
if stability > 0.8:
ensemble.weighting.set_beta(0.9) # Stable -> trust performance
else:
ensemble.weighting.set_beta(0.6) # Volatile -> favor diversity
# Continue normal operation
pred, expert_preds = ensemble.predict(x[t])
ensemble.update(expert_preds, y[t])Comparison with classical ensemble methods across 3 domains:
| Method | Electricity (RMSE↓) | HAR Activity (Acc%↑) | Financial (Sharpe↑) |
|---|---|---|---|
| Best Single Expert | 0.124 ± 0.008 | 91.2 ± 1.1 | 1.42 ± 0.18 |
| Equal Weight | 0.118 ± 0.006 | 92.8 ± 0.9 | 1.58 ± 0.15 |
| Stacking (Offline) | 0.112 ± 0.007 | 93.1 ± 1.0 | 1.61 ± 0.14 |
| Mixture of Experts | 0.109 ± 0.006 | 93.5 ± 0.8 | 1.65 ± 0.16 |
| Hedge Algorithm | 0.107 ± 0.005 | 93.9 ± 0.7 | 1.71 ± 0.12 |
| EARCP | 0.098 ± 0.004 | 94.8 ± 0.6 | 1.89 ± 0.11 |
Average improvement: +10.5% over classical methods
| Operation | Time Complexity | Space Complexity |
|---|---|---|
| Prediction | O(M) | O(M) |
| Coherence | O(M²) | O(M²) |
| Weight Update | O(M) | O(M) |
| Full Step | O(M²) | O(M²) |
For M=10 experts: ~0.5ms per step on modern CPU
Tested successfully with:
- ✅ Up to 50 experts
- ✅ Up to 1M time steps
- ✅ Real-time streaming (1000+ samples/sec)
- ✅ Batch sizes from 1 to 10,000
For pure performance (β=1):
Regret_T ≤ √(2T log M)
With coherence incorporation (β<1):
Regret_T ≤ (1/β) √(2T log M)
where:
- T = number of time steps
- M = number of experts
- β = performance/coherence balance
At each step t, EARCP performs:
-
Performance Update
P_i,t = α_P · P_i,t-1 + (1 - α_P) · (-ℓ_i,t) -
Coherence Computation
C_i,t = 1/(M-1) · Σⱼ≠ᵢ Agreement(pᵢ,ₜ, pⱼ,ₜ) -
Signal Fusion
s_i,t = β · P_i,t + (1 - β) · C_i,t -
Weight Update
w̃_i,t = exp(η_s · s_i,t) w_i,t = max(w_min, w̃_i,t / Σⱼ w̃_j,t)
The regret bound follows from:
- Online convex optimization framework
- Exponential weighting analysis
- Coherence as regularization term
See academic paper for complete proof.
Contributions are welcome! Areas of interest:
- New wrapper classes for ML frameworks
- Additional preset configurations
- Custom aggregation methods
- Tutorial notebooks
- Video tutorials
- Use case examples
- Edge case tests
- Performance benchmarks
- Framework compatibility
- Interactive dashboards
- 3D visualizations
- Real-time monitoring
- New theoretical results
- Benchmark datasets
- Algorithm variants
- Fork the repository
- Create a feature branch:
git checkout -b feature/YourFeature - Commit changes:
git commit -m 'Add YourFeature' - Push to branch:
git push origin feature/YourFeature - Open a Pull Request
See CONTRIBUTING.md for detailed guidelines.
Business Source License 1.1 - Copyright (c) 2025 Mike Amega
- ✅ Academic research and education
- ✅ Personal projects
- ✅ Companies with revenue < $100,000/year
Commercial license required for:
- 💼 Companies with revenue ≥ $100,000/year
- 💼 Embedding in commercial products
- 💼 Offering as SaaS
Contact: info@amewebstudio.com
Automatically becomes Apache 2.0 on November 13, 2029
See LICENSE.md for complete terms.
- GPU-accelerated coherence computation
- Hierarchical EARCP for 100+ experts
- AutoML hyperparameter tuning
- Interactive web dashboard
- Distributed/parallel implementation
- Streaming data pipeline integration
- Custom aggregation methods
- Advanced visualization tools
- Learned coherence functions
- Multi-objective optimization
- Contextual bandits extension
- Production deployment tools
Mike Amega
Independent Researcher & ML Engineer
- Email: info@amewebstudio.com
- LinkedIn: Mike Amega
- GitHub: @Volgat
- Location: Windsor, Ontario, Canada
Documentation & Tutorials
- GitHub Wiki
- Examples Directory
- Video Tutorials (coming soon)
Community
- GitHub Discussions
- Stack Overflow
- Discord Server (coming soon)
Issues & Bugs
- GitHub Issues
- Include: version, minimal code, error message
Commercial Inquiries
- Email: info@amewebstudio.com
- Subject: "EARCP Commercial License"
@article{amega2025earcp,
title={EARCP: Ensemble Auto-Régulé par Cohérence et Performance},
author={Amega, Mike},
year={2025},
journal={arXiv preprint},
url={https://github.com/Volgat/earcp},
note={Prior art established November 13, 2025}
}@software{amega2025earcp_lib,
title={EARCP: Python Library for Adaptive Ensemble Learning},
author={Amega, Mike},
year={2025},
version={1.0.0},
url={https://github.com/Volgat/earcp},
note={PyPI: earcp}
}If EARCP is useful for your work:
- ⭐ Star this repository
- 🔔 Watch for updates
- 🍴 Fork for your modifications
- 📢 Share with colleagues
- 💬 Discuss in GitHub Discussions
EARCP builds upon decades of research in:
- Ensemble learning (Breiman, Freund, Schapire)
- Online learning (Cesa-Bianchi, Lugosi)
- Expert algorithms (Littlestone, Warmuth)
Special thanks to the open-source ML community.
Version: 1.0.0
Release Date: November 13, 2025
Status: Production-Ready ✅
Python: 3.8, 3.9, 3.10, 3.11, 3.12
Copyright © 2025 Mike Amega. All rights reserved.
Prior Art Date: November 13, 2025
License: Business Source License 1.1
Built with ❤️ in Windsor, Ontario, Canada