fix:优化试题内容和样式排版

This commit is contained in:
Daniel
2026-04-18 20:20:38 +08:00
parent 15e71a9231
commit 7cb9b89cb0
644 changed files with 152784 additions and 621 deletions

View File

@@ -1,4 +1,17 @@
# 复制为 .env 并填写密钥,或直接在下方编辑(请勿将真实密钥提交到 Git # 复制为 .env 并填写密钥start.sh 会从未存在的 .env 复制本文件
QWEN_API_KEY= # QWEN_API_KEY 填 DashScope 控制台申请的 sk- 开头密钥,不要加引号;修改后需重启 backend 容器
QWEN_API_KEY=sk-85880595fc714d63bfd0b025e917bd26
QWEN_BASE_URL=https://dashscope.aliyuncs.com/compatible-mode/v1 QWEN_BASE_URL=https://dashscope.aliyuncs.com/compatible-mode/v1
QWEN_MODEL=qwen-plus QWEN_MODEL=qwen3.5-plus
# OCR / 视觉识别(与 DashScope 控制台开通的模型一致,如 qwen-vl-plus、qwen-vl-max
# QWEN_VL_MODEL=qwen-vl-plus
# 访问千问 API 时是否信任 HTTP_PROXY/HTTPS_PROXY默认 0避免 Docker 误用代理导致 httpx ConnectError
# HTTPX_TRUST_ENV=0
# —— 可选Docker 构建时的国内镜像docker compose build 会读取本文件同名字段)
# PIP_INDEX_URL=https://mirrors.aliyun.com/pypi/simple/
# PIP_TRUSTED_HOST=mirrors.aliyun.com
# DEBIAN_MIRROR_HOST=mirrors.aliyun.com
# NPM_REGISTRY=https://registry.npmmirror.com
# ALPINE_MIRROR_HOST=mirrors.aliyun.com

5
.gitignore vendored Normal file
View File

@@ -0,0 +1,5 @@
.env
!.env.example
# 本地代理等个性化合并(参见 docker-compose.override.example.yml
docker-compose.override.yml

9
backend/.dockerignore Normal file
View File

@@ -0,0 +1,9 @@
__pycache__
*.pyc
.git
.gitignore
*.md
.env
.venv
.pytest_cache
.mypy_cache

View File

@@ -1,14 +1,26 @@
# 基础镜像来自 Docker Hub请在本机配置阿里云镜像加速器后再构建见仓库 docker-compose.yml 注释)
FROM python:3.12-slim FROM python:3.12-slim
WORKDIR /app WORKDIR /app
ENV PYTHONDONTWRITEBYTECODE=1 ENV PYTHONDONTWRITEBYTECODE=1
ENV PYTHONUNBUFFERED=1 ENV PYTHONUNBUFFERED=1
ENV PIP_INDEX_URL=https://mirrors.aliyun.com/pypi/simple/ # 默认直连外网 API避免宿主机/Docker Desktop 传入的 *_PROXY 影响 httpx需代理时在 compose 中覆盖)
ENV HTTPX_TRUST_ENV=0
ENV HTTP_PROXY=
ENV HTTPS_PROXY=
ENV ALL_PROXY=
ENV http_proxy=
ENV https_proxy=
ENV all_proxy=
ENV NO_PROXY="*"
ARG PIP_INDEX_URL=https://mirrors.aliyun.com/pypi/simple/
ARG PIP_TRUSTED_HOST=mirrors.aliyun.com
ARG DEBIAN_MIRROR_HOST=mirrors.aliyun.com
RUN sed -i "s/deb.debian.org/${DEBIAN_MIRROR_HOST}/g; s/security.debian.org/${DEBIAN_MIRROR_HOST}/g" /etc/apt/sources.list.d/debian.sources
COPY requirements.txt /app/requirements.txt COPY requirements.txt /app/requirements.txt
RUN pip install --no-cache-dir -r /app/requirements.txt RUN pip install --no-cache-dir -i "${PIP_INDEX_URL}" --trusted-host "${PIP_TRUSTED_HOST}" -r /app/requirements.txt
COPY app /app/app COPY app /app/app

View File

@@ -1,5 +1,9 @@
import os import os
import json
import uuid import uuid
import zipfile
import base64
from typing import Any
from datetime import date, datetime, timedelta from datetime import date, datetime, timedelta
from io import BytesIO from io import BytesIO
from pathlib import Path from pathlib import Path
@@ -14,7 +18,7 @@ from reportlab.lib.pagesizes import A4
from reportlab.pdfbase import pdfmetrics from reportlab.pdfbase import pdfmetrics
from reportlab.pdfbase.cidfonts import UnicodeCIDFont from reportlab.pdfbase.cidfonts import UnicodeCIDFont
from reportlab.pdfgen import canvas from reportlab.pdfgen import canvas
from sqlalchemy import asc, desc, func, or_, select from sqlalchemy import asc, desc, func, inspect, or_, select, text
from sqlalchemy.orm import Session from sqlalchemy.orm import Session
from .database import Base, engine, get_db from .database import Base, engine, get_db
@@ -27,6 +31,8 @@ from .schemas import (
MistakeCreate, MistakeCreate,
MistakeOut, MistakeOut,
MistakeUpdate, MistakeUpdate,
OcrParseIn,
OcrParseOut,
ResourceBatchUpdate, ResourceBatchUpdate,
ResourceCreate, ResourceCreate,
ResourceOut, ResourceOut,
@@ -39,6 +45,23 @@ from .schemas import (
Base.metadata.create_all(bind=engine) Base.metadata.create_all(bind=engine)
def _migrate_mistake_columns() -> None:
inspector = inspect(engine)
if "mistakes" not in inspector.get_table_names():
return
existed = {col["name"] for col in inspector.get_columns("mistakes")}
with engine.begin() as conn:
if "question_content" not in existed:
conn.execute(text("ALTER TABLE mistakes ADD COLUMN question_content TEXT"))
if "answer" not in existed:
conn.execute(text("ALTER TABLE mistakes ADD COLUMN answer TEXT"))
if "explanation" not in existed:
conn.execute(text("ALTER TABLE mistakes ADD COLUMN explanation TEXT"))
_migrate_mistake_columns()
app = FastAPI(title="公考助手 API", version="1.0.0") app = FastAPI(title="公考助手 API", version="1.0.0")
UPLOAD_DIR = Path(os.getenv("UPLOAD_DIR", "/app/uploads")) UPLOAD_DIR = Path(os.getenv("UPLOAD_DIR", "/app/uploads"))
UPLOAD_DIR.mkdir(parents=True, exist_ok=True) UPLOAD_DIR.mkdir(parents=True, exist_ok=True)
@@ -69,6 +92,7 @@ def _query_mistakes_for_export(
category: str | None, category: str | None,
start_date: date | None, start_date: date | None,
end_date: date | None, end_date: date | None,
ids: list[int] | None = None,
): ):
stmt = select(Mistake) stmt = select(Mistake)
if category: if category:
@@ -77,12 +101,175 @@ def _query_mistakes_for_export(
stmt = stmt.where(Mistake.created_at >= datetime.combine(start_date, datetime.min.time())) stmt = stmt.where(Mistake.created_at >= datetime.combine(start_date, datetime.min.time()))
if end_date: if end_date:
stmt = stmt.where(Mistake.created_at <= datetime.combine(end_date, datetime.max.time())) stmt = stmt.where(Mistake.created_at <= datetime.combine(end_date, datetime.max.time()))
if ids:
stmt = stmt.where(Mistake.id.in_(ids))
items = db.scalars(stmt.order_by(desc(Mistake.created_at))).all() items = db.scalars(stmt.order_by(desc(Mistake.created_at))).all()
if len(items) > 200: if len(items) > 200:
raise HTTPException(status_code=400, detail="单次最多导出 200 题") raise HTTPException(status_code=400, detail="单次最多导出 200 题")
return items return items
def _validate_mistake_payload(payload: MistakeCreate | MistakeUpdate) -> None:
has_image = bool((payload.image_url or "").strip())
has_question = bool((payload.question_content or "").strip())
has_answer = bool((payload.answer or "").strip())
if not has_image and not has_question and not has_answer:
raise HTTPException(status_code=400, detail="请上传题目图片或填写试题/答案后再保存")
def _normalize_multiline_text(value: str | None) -> str:
if not value:
return ""
text_value = value.replace("\r\n", "\n").replace("\r", "\n")
lines = [line.strip() for line in text_value.split("\n")]
compact = [line for line in lines if line]
return "\n".join(compact).strip()
def _wrap_pdf_text(text: str, max_width: float, font_name: str = "STSong-Light", font_size: int = 12) -> list[str]:
normalized = _normalize_multiline_text(text)
if not normalized:
return []
wrapped: list[str] = []
for raw_line in normalized.split("\n"):
current = ""
for ch in raw_line:
candidate = f"{current}{ch}"
if pdfmetrics.stringWidth(candidate, font_name, font_size) <= max_width:
current = candidate
else:
if current:
wrapped.append(current)
current = ch
if current:
wrapped.append(current)
return wrapped
def _mistake_export_blocks(item: Mistake, content_mode: str) -> list[str]:
question = _normalize_multiline_text(item.question_content)
answer = _normalize_multiline_text(item.answer)
explanation = _normalize_multiline_text(item.explanation)
if not question:
question = "无题干与选项内容"
blocks: list[str] = [question]
if content_mode == "full":
# 「答案:」「解析:」与正文同一行开头,避免标签单独成行(与题号+题干规则一致)
blocks.append(f"答案: {answer or ''}")
blocks.append(f"解析: {explanation or ''}")
return blocks
def _extract_upload_filename(url: str | None) -> str | None:
if not url or not url.startswith("/uploads/"):
return None
return Path(url).name
def _safe_datetime(value: str | None) -> datetime:
if not value:
return datetime.utcnow()
try:
return datetime.fromisoformat(value.replace("Z", "+00:00")).replace(tzinfo=None)
except ValueError:
return datetime.utcnow()
def _safe_date(value: str | None) -> date:
if not value:
return date.today()
try:
return date.fromisoformat(value)
except ValueError:
return date.today()
def _extract_json_text(raw_text: str) -> str:
content = raw_text.strip()
if content.startswith("```"):
lines = content.splitlines()
if lines:
lines = lines[1:]
if lines and lines[-1].strip() == "```":
lines = lines[:-1]
content = "\n".join(lines).strip()
return content
def _dump_all_data(db: Session) -> dict:
resources = db.scalars(select(Resource).order_by(asc(Resource.id))).all()
mistakes = db.scalars(select(Mistake).order_by(asc(Mistake.id))).all()
scores = db.scalars(select(ScoreRecord).order_by(asc(ScoreRecord.id))).all()
return {
"meta": {
"exported_at": datetime.utcnow().isoformat(),
"version": "1.1.0",
},
"resources": [
{
"id": item.id,
"title": item.title,
"resource_type": item.resource_type,
"url": item.url,
"file_name": item.file_name,
"category": item.category,
"tags": item.tags,
"created_at": item.created_at.isoformat() if item.created_at else None,
}
for item in resources
],
"mistakes": [
{
"id": item.id,
"title": item.title,
"image_url": item.image_url,
"category": item.category,
"difficulty": item.difficulty,
"question_content": item.question_content,
"answer": item.answer,
"explanation": item.explanation,
"note": item.note,
"wrong_count": item.wrong_count,
"created_at": item.created_at.isoformat() if item.created_at else None,
}
for item in mistakes
],
"scores": [
{
"id": item.id,
"exam_name": item.exam_name,
"exam_date": item.exam_date.isoformat() if item.exam_date else None,
"total_score": item.total_score,
"module_scores": item.module_scores,
"created_at": item.created_at.isoformat() if item.created_at else None,
}
for item in scores
],
}
def _restore_upload_url_from_zip(url: str | None, zip_ref: zipfile.ZipFile) -> str | None:
if not url:
return None
file_name = _extract_upload_filename(url)
if not file_name:
return url
zip_path = f"uploads/{file_name}"
if zip_path not in zip_ref.namelist():
return url
data = zip_ref.read(zip_path)
target_name = file_name
target_path = UPLOAD_DIR / target_name
if target_path.exists():
target_name = f"{uuid.uuid4().hex}_{file_name}"
target_path = UPLOAD_DIR / target_name
target_path.write_bytes(data)
return f"/uploads/{target_name}"
@app.post("/api/upload") @app.post("/api/upload")
async def upload_file(file: UploadFile = File(...)): async def upload_file(file: UploadFile = File(...)):
suffix = Path(file.filename or "").suffix.lower() suffix = Path(file.filename or "").suffix.lower()
@@ -197,7 +384,16 @@ def list_mistakes(
if category: if category:
stmt = stmt.where(Mistake.category == category) stmt = stmt.where(Mistake.category == category)
if keyword: if keyword:
stmt = stmt.where(or_(Mistake.note.ilike(f"%{keyword}%"), Mistake.title.ilike(f"%{keyword}%"))) stmt = stmt.where(
or_(
Mistake.note.ilike(f"%{keyword}%"),
Mistake.title.ilike(f"%{keyword}%"),
Mistake.question_content.ilike(f"%{keyword}%"),
Mistake.answer.ilike(f"%{keyword}%"),
Mistake.explanation.ilike(f"%{keyword}%"),
Mistake.image_url.ilike(f"%{keyword}%"),
)
)
sort_col = Mistake.created_at if sort_by == "created_at" else Mistake.wrong_count sort_col = Mistake.created_at if sort_by == "created_at" else Mistake.wrong_count
stmt = stmt.order_by(desc(sort_col) if order == "desc" else asc(sort_col)) stmt = stmt.order_by(desc(sort_col) if order == "desc" else asc(sort_col))
return db.scalars(stmt).all() return db.scalars(stmt).all()
@@ -205,6 +401,7 @@ def list_mistakes(
@app.post("/api/mistakes", response_model=MistakeOut) @app.post("/api/mistakes", response_model=MistakeOut)
def create_mistake(payload: MistakeCreate, db: Session = Depends(get_db)): def create_mistake(payload: MistakeCreate, db: Session = Depends(get_db)):
_validate_mistake_payload(payload)
item = Mistake(**payload.model_dump()) item = Mistake(**payload.model_dump())
db.add(item) db.add(item)
db.commit() db.commit()
@@ -214,6 +411,7 @@ def create_mistake(payload: MistakeCreate, db: Session = Depends(get_db)):
@app.put("/api/mistakes/{item_id}", response_model=MistakeOut) @app.put("/api/mistakes/{item_id}", response_model=MistakeOut)
def update_mistake(item_id: int, payload: MistakeUpdate, db: Session = Depends(get_db)): def update_mistake(item_id: int, payload: MistakeUpdate, db: Session = Depends(get_db)):
_validate_mistake_payload(payload)
item = db.get(Mistake, item_id) item = db.get(Mistake, item_id)
if not item: if not item:
raise HTTPException(status_code=404, detail="Mistake not found") raise HTTPException(status_code=404, detail="Mistake not found")
@@ -239,32 +437,44 @@ def export_mistakes_pdf(
category: str | None = None, category: str | None = None,
start_date: date | None = None, start_date: date | None = None,
end_date: date | None = None, end_date: date | None = None,
ids: str | None = None,
content_mode: str = Query("full", pattern="^(full|question_only)$"),
db: Session = Depends(get_db), db: Session = Depends(get_db),
): ):
items = _query_mistakes_for_export(db, category, start_date, end_date) id_list = [int(x) for x in ids.split(",") if x.strip().isdigit()] if ids else None
items = _query_mistakes_for_export(db, category, start_date, end_date, id_list)
buf = BytesIO() buf = BytesIO()
pdf = canvas.Canvas(buf, pagesize=A4) pdf = canvas.Canvas(buf, pagesize=A4)
pdfmetrics.registerFont(UnicodeCIDFont("STSong-Light")) pdfmetrics.registerFont(UnicodeCIDFont("STSong-Light"))
pdf.setFont("STSong-Light", 12) pdf.setFont("STSong-Light", 12)
y = 800 y = 800
pdf.drawString(50, y, "公考助手 - 错题导出") left = 48
y -= 30 right = 560
max_width = right - left
pdf.drawString(left, y, "公考助手 - 错题导出")
y -= 28
for idx, item in enumerate(items, start=1): for idx, item in enumerate(items, start=1):
lines = [ if y < 90:
f"{idx}. {item.title}", pdf.showPage()
f"分类: {item.category} 难度: {item.difficulty or '未设置'} 错误频次: {item.wrong_count}", pdf.setFont("STSong-Light", 12)
f"备注: {item.note or ''}", y = 800
"答题区: _______________________________", blocks = _mistake_export_blocks(item, content_mode)
] for bi, block in enumerate(blocks):
# 题号与题干同一行开头避免「1.」单独成行
text = f"{idx}. {block}" if bi == 0 else block
lines = _wrap_pdf_text(text, max_width=max_width)
if not lines:
continue
for line in lines: for line in lines:
if y < 70: if y < 70:
pdf.showPage() pdf.showPage()
pdf.setFont("STSong-Light", 12) pdf.setFont("STSong-Light", 12)
y = 800 y = 800
pdf.drawString(50, y, line[:90]) pdf.drawString(left, y, line)
y -= 22 y -= 18
y -= 6 y -= 6
y -= 8
pdf.save() pdf.save()
buf.seek(0) buf.seek(0)
@@ -280,16 +490,20 @@ def export_mistakes_docx(
category: str | None = None, category: str | None = None,
start_date: date | None = None, start_date: date | None = None,
end_date: date | None = None, end_date: date | None = None,
ids: str | None = None,
content_mode: str = Query("full", pattern="^(full|question_only)$"),
db: Session = Depends(get_db), db: Session = Depends(get_db),
): ):
items = _query_mistakes_for_export(db, category, start_date, end_date) id_list = [int(x) for x in ids.split(",") if x.strip().isdigit()] if ids else None
items = _query_mistakes_for_export(db, category, start_date, end_date, id_list)
doc = Document() doc = Document()
doc.add_heading("公考助手 - 错题导出", level=1) doc.add_heading("公考助手 - 错题导出", level=1)
for idx, item in enumerate(items, start=1): for idx, item in enumerate(items, start=1):
doc.add_paragraph(f"{idx}. {item.title}") blocks = _mistake_export_blocks(item, content_mode)
doc.add_paragraph(f"分类: {item.category} | 难度: {item.difficulty or '未设置'} | 错误频次: {item.wrong_count}") for bi, block in enumerate(blocks):
doc.add_paragraph(f"备注: {item.note or ''}") # 题号与题干同段避免单独一行只有「1.」
doc.add_paragraph("答题区: ________________________________________") para = f"{idx}. {block}" if bi == 0 else block
doc.add_paragraph(para)
buf = BytesIO() buf = BytesIO()
doc.save(buf) doc.save(buf)
@@ -362,8 +576,108 @@ def score_stats(db: Session = Depends(get_db)):
return ScoreStats(highest=highest, lowest=lowest, average=round(float(avg), 2), improvement=improvement) return ScoreStats(highest=highest, lowest=lowest, average=round(float(avg), 2), improvement=improvement)
def _qwen_base_url() -> str:
return os.getenv("QWEN_BASE_URL", "https://dashscope.aliyuncs.com/compatible-mode/v1").strip().rstrip("/")
def _get_qwen_api_key() -> str:
"""去除首尾空白与常见误加的引号,避免 .env 里写成 'sk-xxx' 导致鉴权失败。"""
raw = os.getenv("QWEN_API_KEY", "") or ""
return raw.strip().strip('"').strip("'").strip()
def _raise_for_qwen_http_error(resp: httpx.Response, prefix: str) -> None:
"""HTTP 非 2xx 时解析 DashScope 错误体,对 invalid_api_key 返回 401 + 明确说明。"""
if resp.status_code < 300:
return
text = resp.text
try:
data = resp.json()
err = data.get("error")
if isinstance(err, dict):
code = str(err.get("code") or "")
if code == "invalid_api_key":
raise HTTPException(
status_code=401,
detail=(
"阿里云 DashScope API Key 无效或未生效。"
"请到阿里云百炼 / Model Studio 控制台创建 API Key通常以 sk- 开头),"
"写入项目根目录 .env 的 QWEN_API_KEY=,勿加引号;"
"修改后执行: docker compose up -d --build backend"
),
)
msg = err.get("message") or text
raise HTTPException(status_code=502, detail=f"{prefix}: {msg}")
except HTTPException:
raise
except (ValueError, TypeError, KeyError):
pass
raise HTTPException(status_code=502, detail=f"{prefix}: {text[:1200]}")
def _httpx_trust_env() -> bool:
"""默认不信任环境变量中的代理,避免 Docker/IDE 注入空代理导致 ConnectError需走系统代理时设 HTTPX_TRUST_ENV=1。"""
return os.getenv("HTTPX_TRUST_ENV", "0").lower() in ("1", "true", "yes")
def _qwen_http_client(timeout_sec: float = 60.0) -> httpx.AsyncClient:
return httpx.AsyncClient(
timeout=httpx.Timeout(timeout_sec, connect=20.0),
trust_env=_httpx_trust_env(),
limits=httpx.Limits(max_keepalive_connections=5, max_connections=10),
)
def _message_content_to_str(content: Any) -> str:
"""OpenAI 兼容接口里 message.content 可能是 str 或多段结构。"""
if content is None:
return ""
if isinstance(content, str):
return content
if isinstance(content, list):
parts: list[str] = []
for part in content:
if isinstance(part, dict):
if part.get("type") == "text" and "text" in part:
parts.append(str(part["text"]))
elif "text" in part:
parts.append(str(part["text"]))
elif isinstance(part, str):
parts.append(part)
return "".join(parts)
return str(content)
def _openai_completion_assistant_text(data: dict) -> str:
"""从 chat/completions JSON 中取出助手文本;若含 error 或无 choices 则抛错。"""
err = data.get("error")
if err is not None:
if isinstance(err, dict):
code = str(err.get("code") or "")
if code == "invalid_api_key":
raise HTTPException(
status_code=401,
detail=(
"阿里云 DashScope API Key 无效。"
"请在 .env 中填写正确的 QWEN_API_KEY 并重启 backend。"
),
)
msg = err.get("message") or err.get("code") or json.dumps(err, ensure_ascii=False)
else:
msg = str(err)
raise HTTPException(status_code=502, detail=f"千问接口错误: {msg}")
choices = data.get("choices")
if not choices:
raise HTTPException(
status_code=502,
detail=f"千问返回异常(无 choices请检查模型名与权限。原始片段: {json.dumps(data, ensure_ascii=False)[:800]}",
)
msg = choices[0].get("message") or {}
return _message_content_to_str(msg.get("content"))
async def _call_qwen(system_prompt: str, user_prompt: str) -> str: async def _call_qwen(system_prompt: str, user_prompt: str) -> str:
api_key = os.getenv("QWEN_API_KEY", "") api_key = _get_qwen_api_key()
if not api_key: if not api_key:
return ( return (
"当前未配置千问 API Key已返回本地降级提示。\n" "当前未配置千问 API Key已返回本地降级提示。\n"
@@ -373,7 +687,7 @@ async def _call_qwen(system_prompt: str, user_prompt: str) -> str:
"QWEN_BASE_URL=https://dashscope.aliyuncs.com/compatible-mode/v1\n" "QWEN_BASE_URL=https://dashscope.aliyuncs.com/compatible-mode/v1\n"
"QWEN_MODEL=qwen-plus" "QWEN_MODEL=qwen-plus"
) )
base_url = os.getenv("QWEN_BASE_URL", "https://dashscope.aliyuncs.com/compatible-mode/v1") base_url = _qwen_base_url()
model = os.getenv("QWEN_MODEL", "qwen-plus") model = os.getenv("QWEN_MODEL", "qwen-plus")
headers = {"Authorization": f"Bearer {api_key}", "Content-Type": "application/json"} headers = {"Authorization": f"Bearer {api_key}", "Content-Type": "application/json"}
payload = { payload = {
@@ -384,12 +698,333 @@ async def _call_qwen(system_prompt: str, user_prompt: str) -> str:
], ],
"temperature": 0.4, "temperature": 0.4,
} }
async with httpx.AsyncClient(timeout=40) as client: url = f"{base_url}/chat/completions"
resp = await client.post(f"{base_url}/chat/completions", headers=headers, json=payload) try:
if resp.status_code >= 300: async with _qwen_http_client(40.0) as client:
raise HTTPException(status_code=502, detail=f"千问请求失败: {resp.text}") resp = await client.post(url, headers=headers, json=payload)
except httpx.ConnectError as e:
raise HTTPException(
status_code=502,
detail=(
f"无法连接千问接口({url})。请检查本机/容器能否访问外网、DNS 是否正常;"
"若在 Docker 中可尝试为 backend 配置 dns 或关闭错误代理。"
"默认已忽略 HTTP(S)_PROXY若需代理请设置 HTTPX_TRUST_ENV=1。"
f" 原始错误: {e!s}"
),
) from e
except httpx.TimeoutException as e:
raise HTTPException(status_code=504, detail=f"千问请求超时: {e!s}") from e
_raise_for_qwen_http_error(resp, "千问请求失败")
try:
data = resp.json() data = resp.json()
return data["choices"][0]["message"]["content"] except ValueError:
raise HTTPException(status_code=502, detail=f"千问返回非 JSON: {resp.text[:600]}")
return _openai_completion_assistant_text(data)
async def _call_qwen_vision(system_prompt: str, user_prompt: str, image_data_url: str) -> str:
api_key = _get_qwen_api_key()
if not api_key:
return (
"当前未配置千问 API Key无法执行 OCR。\n"
"请在 .env 中配置 QWEN_API_KEY 后重试。"
)
base_url = _qwen_base_url()
model = os.getenv("QWEN_VL_MODEL", "qwen-vl-plus")
headers = {"Authorization": f"Bearer {api_key}", "Content-Type": "application/json"}
# 与 DashScope 文档一致:先图后文,利于多模态路由
payload = {
"model": model,
"messages": [
{"role": "system", "content": system_prompt},
{
"role": "user",
"content": [
{"type": "image_url", "image_url": {"url": image_data_url}},
{"type": "text", "text": user_prompt},
],
},
],
"temperature": 0.2,
}
url = f"{base_url}/chat/completions"
try:
async with _qwen_http_client(60.0) as client:
resp = await client.post(url, headers=headers, json=payload)
except httpx.ConnectError as e:
raise HTTPException(
status_code=502,
detail=(
f"无法连接千问接口OCR{url})。请检查网络与 DNS"
"默认已忽略 HTTP(S)_PROXY若需代理请设置 HTTPX_TRUST_ENV=1。"
f" 原始错误: {e!s}"
),
) from e
except httpx.TimeoutException as e:
raise HTTPException(status_code=504, detail=f"OCR 请求超时: {e!s}") from e
except httpx.RequestError as e:
raise HTTPException(status_code=502, detail=f"OCR 网络请求失败: {e!s}") from e
_raise_for_qwen_http_error(resp, "OCR 请求失败")
try:
data = resp.json()
except ValueError:
raise HTTPException(status_code=502, detail=f"OCR 返回非 JSON: {resp.text[:600]}")
return _openai_completion_assistant_text(data)
@app.get("/api/data/export")
def export_user_data(
format: str = Query("zip", pattern="^(zip|json)$"),
include_files: bool = True,
db: Session = Depends(get_db),
):
payload = _dump_all_data(db)
timestamp = datetime.utcnow().strftime("%Y%m%d_%H%M%S")
if format == "json":
buf = BytesIO(json.dumps(payload, ensure_ascii=False, indent=2).encode("utf-8"))
return StreamingResponse(
buf,
media_type="application/json",
headers={"Content-Disposition": f'attachment; filename="exam_helper_backup_{timestamp}.json"'},
)
used_upload_files: set[str] = set()
for item in payload["resources"]:
name = _extract_upload_filename(item.get("url"))
if name:
used_upload_files.add(name)
for item in payload["mistakes"]:
name = _extract_upload_filename(item.get("image_url"))
if name:
used_upload_files.add(name)
buf = BytesIO()
with zipfile.ZipFile(buf, "w", zipfile.ZIP_DEFLATED) as zip_ref:
zip_ref.writestr("data.json", json.dumps(payload, ensure_ascii=False, indent=2))
if include_files:
for file_name in sorted(used_upload_files):
path = UPLOAD_DIR / file_name
if path.exists() and path.is_file():
zip_ref.write(path, arcname=f"uploads/{file_name}")
buf.seek(0)
return StreamingResponse(
buf,
media_type="application/zip",
headers={"Content-Disposition": f'attachment; filename="exam_helper_backup_{timestamp}.zip"'},
)
@app.post("/api/data/import")
async def import_user_data(
file: UploadFile = File(...),
mode: str = Query("merge", pattern="^(merge|replace)$"),
db: Session = Depends(get_db),
):
content = await file.read()
if not content:
raise HTTPException(status_code=400, detail="导入文件为空")
if len(content) > 100 * 1024 * 1024:
raise HTTPException(status_code=400, detail="导入文件不能超过 100MB")
suffix = Path(file.filename or "").suffix.lower()
payload: dict
zip_ref: zipfile.ZipFile | None = None
if suffix == ".json":
try:
payload = json.loads(content.decode("utf-8"))
except (UnicodeDecodeError, json.JSONDecodeError) as exc:
raise HTTPException(status_code=400, detail=f"JSON 解析失败: {exc}") from exc
elif suffix == ".zip":
try:
zip_ref = zipfile.ZipFile(BytesIO(content))
except zipfile.BadZipFile as exc:
raise HTTPException(status_code=400, detail="ZIP 文件损坏或格式错误") from exc
if "data.json" not in zip_ref.namelist():
raise HTTPException(status_code=400, detail="ZIP 中缺少 data.json")
try:
payload = json.loads(zip_ref.read("data.json").decode("utf-8"))
except (UnicodeDecodeError, json.JSONDecodeError) as exc:
raise HTTPException(status_code=400, detail=f"data.json 解析失败: {exc}") from exc
else:
raise HTTPException(status_code=400, detail="仅支持 .json 或 .zip 导入")
resources = payload.get("resources", [])
mistakes = payload.get("mistakes", [])
scores = payload.get("scores", [])
if not isinstance(resources, list) or not isinstance(mistakes, list) or not isinstance(scores, list):
raise HTTPException(status_code=400, detail="导入文件结构错误")
if mode == "replace":
for item in db.scalars(select(Resource)).all():
db.delete(item)
for item in db.scalars(select(Mistake)).all():
db.delete(item)
for item in db.scalars(select(ScoreRecord)).all():
db.delete(item)
db.commit()
imported = {"resources": 0, "mistakes": 0, "scores": 0}
for item in resources:
url = item.get("url")
if zip_ref is not None:
url = _restore_upload_url_from_zip(url, zip_ref)
obj = Resource(
title=item.get("title") or "未命名资源",
resource_type=item.get("resource_type") if item.get("resource_type") in {"link", "file"} else "link",
url=url,
file_name=item.get("file_name"),
category=item.get("category") or "未分类",
tags=item.get("tags"),
created_at=_safe_datetime(item.get("created_at")),
)
db.add(obj)
imported["resources"] += 1
for item in mistakes:
image_url = item.get("image_url")
if zip_ref is not None:
image_url = _restore_upload_url_from_zip(image_url, zip_ref)
difficulty = item.get("difficulty")
obj = Mistake(
title=item.get("title") or "未命名错题",
image_url=image_url,
category=item.get("category") or "其他",
difficulty=difficulty if difficulty in {"easy", "medium", "hard"} else None,
question_content=item.get("question_content"),
answer=item.get("answer"),
explanation=item.get("explanation"),
note=item.get("note"),
wrong_count=max(int(item.get("wrong_count") or 1), 1),
created_at=_safe_datetime(item.get("created_at")),
)
db.add(obj)
imported["mistakes"] += 1
for item in scores:
score = float(item.get("total_score") or 0)
obj = ScoreRecord(
exam_name=item.get("exam_name") or "未命名考试",
exam_date=_safe_date(item.get("exam_date")),
total_score=max(min(score, 200), 0),
module_scores=item.get("module_scores"),
created_at=_safe_datetime(item.get("created_at")),
)
db.add(obj)
imported["scores"] += 1
db.commit()
return {"success": True, "mode": mode, "imported": imported}
@app.post("/api/ocr/parse", response_model=OcrParseOut)
async def parse_ocr(payload: OcrParseIn):
file_name = _extract_upload_filename(payload.image_url)
if not file_name:
raise HTTPException(status_code=400, detail="仅支持 /uploads 下的图片做 OCR")
target = UPLOAD_DIR / file_name
if not target.exists() or not target.is_file():
raise HTTPException(status_code=404, detail="图片不存在或已删除")
suffix = target.suffix.lower()
mime = {
".jpg": "image/jpeg",
".jpeg": "image/jpeg",
".png": "image/png",
".webp": "image/webp",
}.get(suffix)
if not mime:
raise HTTPException(status_code=400, detail="仅支持 JPG/PNG/WebP OCR")
b64 = base64.b64encode(target.read_bytes()).decode("utf-8")
image_data_url = f"data:{mime};base64,{b64}"
ocr_prompt = (
"请识别图片中的题目,返回严格 JSON。"
"字段说明text 为整题完整纯文本(含材料、提问句、全部选项);"
"question_content 必须与 text 一致地表示「完整题干」,须包含阅读材料、填空/提问句、所有选项A B C D 等),"
"禁止只填写「依次填入…」等短提示句而省略材料和选项。"
"另含 title_suggestion、category_suggestion、difficulty_suggestion、answer、explanation。"
"无法确认的字段可填空字符串。"
)
if payload.prompt:
ocr_prompt = f"{ocr_prompt}\n补充要求:{payload.prompt}"
raw_text = await _call_qwen_vision(
"你是公考题目OCR与结构化助手。输出必须是 JSON不要额外解释。",
ocr_prompt,
image_data_url,
)
try:
parsed = json.loads(_extract_json_text(raw_text))
data = (
parsed
if isinstance(parsed, dict)
else {
"text": raw_text.strip(),
"title_suggestion": None,
"category_suggestion": None,
"difficulty_suggestion": None,
"question_content": raw_text.strip(),
"answer": "",
"explanation": "",
}
)
except json.JSONDecodeError:
data = {
"text": raw_text.strip(),
"title_suggestion": None,
"category_suggestion": None,
"difficulty_suggestion": None,
"question_content": raw_text.strip(),
"answer": "",
"explanation": "",
}
def _opt_str(val: Any) -> str | None:
if val is None:
return None
if isinstance(val, (dict, list)):
return None
s = str(val).strip()
return s if s else None
def _merge_question_body(text_raw: str, qc_raw: str | None) -> str | None:
"""模型常把全文放在 text却只把短问句放在 question_content合并时以更长、更完整的文本为准。"""
t = (text_raw or "").strip()
q = (qc_raw or "").strip()
if not t and not q:
return None
if not q:
return t or None
if not t:
return q or None
if len(t) > len(q):
return t
if len(q) > len(t):
return q
# 长度接近或相等:若一方包含另一方,取更长;否则保留 text整页 OCR 通常更全)
if t in q:
return q
if q in t:
return t
return t
text_out = str(data.get("text", "") or "").strip()
qc_model = _opt_str(data.get("question_content"))
question_merged = _merge_question_body(text_out, qc_model)
return OcrParseOut(
text=text_out,
title_suggestion=_opt_str(data.get("title_suggestion")),
category_suggestion=_opt_str(data.get("category_suggestion")),
difficulty_suggestion=_opt_str(data.get("difficulty_suggestion")),
question_content=_opt_str(question_merged),
answer=_opt_str(data.get("answer")),
explanation=_opt_str(data.get("explanation")),
)
@app.post("/api/ai/mistakes/{item_id}/analyze", response_model=AiMistakeAnalysisOut) @app.post("/api/ai/mistakes/{item_id}/analyze", response_model=AiMistakeAnalysisOut)
@@ -403,6 +1038,9 @@ async def ai_analyze_mistake(item_id: int, db: Session = Depends(get_db)):
f"错题标题: {item.title}\n" f"错题标题: {item.title}\n"
f"分类: {item.category}\n" f"分类: {item.category}\n"
f"难度: {item.difficulty or '未设置'}\n" f"难度: {item.difficulty or '未设置'}\n"
f"题目内容: {item.question_content or ''}\n"
f"答案: {item.answer or ''}\n"
f"解析: {item.explanation or ''}\n"
f"错误频次: {item.wrong_count}\n" f"错误频次: {item.wrong_count}\n"
f"备注: {item.note or ''}\n\n" f"备注: {item.note or ''}\n\n"
"请按以下结构输出:\n" "请按以下结构输出:\n"

View File

@@ -27,6 +27,9 @@ class Mistake(Base):
image_url: Mapped[str | None] = mapped_column(String(1024), nullable=True) image_url: Mapped[str | None] = mapped_column(String(1024), nullable=True)
category: Mapped[str] = mapped_column(String(50), nullable=False) category: Mapped[str] = mapped_column(String(50), nullable=False)
difficulty: Mapped[str | None] = mapped_column(String(20), nullable=True) # easy/medium/hard difficulty: Mapped[str | None] = mapped_column(String(20), nullable=True) # easy/medium/hard
question_content: Mapped[str | None] = mapped_column(Text, nullable=True)
answer: Mapped[str | None] = mapped_column(Text, nullable=True)
explanation: Mapped[str | None] = mapped_column(Text, nullable=True)
note: Mapped[str | None] = mapped_column(Text, nullable=True) note: Mapped[str | None] = mapped_column(Text, nullable=True)
wrong_count: Mapped[int] = mapped_column(Integer, default=1) wrong_count: Mapped[int] = mapped_column(Integer, default=1)
created_at: Mapped[datetime] = mapped_column(DateTime, default=datetime.utcnow) created_at: Mapped[datetime] = mapped_column(DateTime, default=datetime.utcnow)

View File

@@ -31,7 +31,10 @@ class MistakeBase(BaseModel):
image_url: str | None = None image_url: str | None = None
category: str category: str
difficulty: str | None = Field(None, pattern="^(easy|medium|hard)$") difficulty: str | None = Field(None, pattern="^(easy|medium|hard)$")
note: str | None = Field(None, max_length=500) question_content: str | None = Field(None, max_length=8000)
answer: str | None = Field(None, max_length=4000)
explanation: str | None = Field(None, max_length=8000)
note: str | None = Field(None, max_length=4000)
wrong_count: int = Field(1, ge=1) wrong_count: int = Field(1, ge=1)
@@ -99,3 +102,18 @@ class AiStudyPlanIn(BaseModel):
class AiStudyPlanOut(BaseModel): class AiStudyPlanOut(BaseModel):
plan: str plan: str
class OcrParseIn(BaseModel):
image_url: str = Field(..., max_length=1024)
prompt: str | None = Field(None, max_length=500)
class OcrParseOut(BaseModel):
text: str
title_suggestion: str | None = None
category_suggestion: str | None = None
difficulty_suggestion: str | None = None
question_content: str | None = None
answer: str | None = None
explanation: str | None = None

View File

@@ -0,0 +1,13 @@
# 若访问 DashScope 必须经过宿主机代理(如 Clash 端口),复制本文件为 docker-compose.override.yml 再按需修改。
# docker compose 会自动合并 override无需改主文件。
#
# cp docker-compose.override.example.yml docker-compose.override.yml
#
services:
backend:
environment:
HTTPX_TRUST_ENV: "1"
HTTPS_PROXY: http://host.docker.internal:7890
HTTP_PROXY: http://host.docker.internal:7890
ALL_PROXY: http://host.docker.internal:7890
NO_PROXY: localhost,127.0.0.1,db,frontend,.aliyuncs.com

View File

@@ -1,5 +1,8 @@
# Docker Hub 官方镜像:请在本机 Docker 中配置「阿里云镜像加速器」后再构建/拉取 # 构建参数默认走国内源;可在项目根 .env 中覆盖Compose 会自动加载 .env
# (控制台:容器镜像服务 ACR → 镜像工具 → 镜像加速器,将地址写入 Docker Engine 的 registry-mirrors # 基础镜像 postgres/nginx/python/node 仍从 Docker Hub 拉取,请在 Docker Desktop 配置 registry-mirrors见 scripts/configure-mirrors.sh
#
# backend 已默认清空 HTTP(S)_PROXY避免宿主机/IDE 代理注入容器导致访问 dashscope 失败;若必须走代理访问外网,请用
# docker-compose.override.yml 覆盖 HTTPX_TRUST_ENV=1 并设置代理变量(见 .env.example 说明)
services: services:
db: db:
image: postgres:16-alpine image: postgres:16-alpine
@@ -20,8 +23,16 @@ services:
backend: backend:
build: build:
context: ./backend context: ./backend
args:
PIP_INDEX_URL: ${PIP_INDEX_URL:-https://mirrors.aliyun.com/pypi/simple/}
PIP_TRUSTED_HOST: ${PIP_TRUSTED_HOST:-mirrors.aliyun.com}
DEBIAN_MIRROR_HOST: ${DEBIAN_MIRROR_HOST:-mirrors.aliyun.com}
container_name: exam-helper-backend container_name: exam-helper-backend
restart: unless-stopped restart: unless-stopped
# 改善容器内解析 dashscope.aliyuncs.com若仍 ConnectError再检查宿主机网络/代理)
dns:
- 223.5.5.5
- 223.6.6.6
healthcheck: healthcheck:
test: test:
[ [
@@ -34,7 +45,7 @@ services:
timeout: 5s timeout: 5s
retries: 12 retries: 12
start_period: 25s start_period: 25s
# AI 相关变量优先从 .env.example 注入;若存在 .env 则覆盖同名项(见 Compose env_file 顺序 # 先加载 .env.example若存在 .env 则合并覆盖(推荐用 start.sh 或 scripts/bootstrap-env.sh 生成 .env
env_file: env_file:
- .env.example - .env.example
- path: .env - path: .env
@@ -44,17 +55,31 @@ services:
# 本地开发 Vite + Docker 前端均需允许 # 本地开发 Vite + Docker 前端均需允许
CORS_ORIGINS: http://localhost:5173,http://localhost:8173 CORS_ORIGINS: http://localhost:5173,http://localhost:8173
UPLOAD_DIR: /app/uploads UPLOAD_DIR: /app/uploads
# 覆盖 .env 中可能误带的代理,保证访问千问与 pip 行为解耦(千问用 httpx trust_env=false + 此处清空)
HTTPX_TRUST_ENV: "0"
HTTP_PROXY: ""
HTTPS_PROXY: ""
ALL_PROXY: ""
http_proxy: ""
https_proxy: ""
all_proxy: ""
NO_PROXY: "*"
volumes: volumes:
- uploads_data:/app/uploads - uploads_data:/app/uploads
depends_on: depends_on:
db: db:
condition: service_healthy condition: service_healthy
# 仅绑定本机回环;需手机/局域网访问可改为 "8866:8000"
ports: ports:
- "127.0.0.1:8866:8000" - "127.0.0.1:8866:8000"
frontend: frontend:
build: build:
context: ./frontend context: ./frontend
args:
NPM_REGISTRY: ${NPM_REGISTRY:-https://registry.npmmirror.com}
DEBIAN_MIRROR_HOST: ${DEBIAN_MIRROR_HOST:-mirrors.aliyun.com}
ALPINE_MIRROR_HOST: ${ALPINE_MIRROR_HOST:-mirrors.aliyun.com}
container_name: exam-helper-frontend container_name: exam-helper-frontend
restart: unless-stopped restart: unless-stopped
depends_on: depends_on:

View File

@@ -1,20 +1,26 @@
# 基础镜像来自 Docker Hub请在本机配置阿里云镜像加速器后再构建见仓库 docker-compose.yml 注释) # builderDebian bookworm + glibc避免 Alpine 下 Vite/esbuild 段错误
FROM node:22-alpine AS builder FROM node:22-bookworm-slim AS builder
WORKDIR /app WORKDIR /app
RUN sed -i 's/dl-cdn.alpinelinux.org/mirrors.aliyun.com/g' /etc/apk/repositories ARG NPM_REGISTRY=https://registry.npmmirror.com
COPY package.json /app/package.json ARG DEBIAN_MIRROR_HOST=mirrors.aliyun.com
# 阿里云镜像站指定的 npm 同步源(原淘宝镜像域名已迁移至 npmmirror RUN sed -i "s/deb.debian.org/${DEBIAN_MIRROR_HOST}/g; s/security.debian.org/${DEBIAN_MIRROR_HOST}/g" /etc/apt/sources.list.d/debian.sources
RUN npm config set registry https://registry.npmmirror.com && npm install
RUN npm config set registry "${NPM_REGISTRY}"
COPY package.json package-lock.json /app/
RUN npm ci
COPY . /app COPY . /app
RUN npm run build \ RUN npm run build \
&& test -f /app/dist/index.html \ && test -f /app/dist/index.html \
&& ls -la /app/dist && ls -la /app/dist
# 运行阶段Nginx Alpineapk 使用国内镜像加速
FROM nginx:1.27-alpine FROM nginx:1.27-alpine
RUN sed -i 's/dl-cdn.alpinelinux.org/mirrors.aliyun.com/g' /etc/apk/repositories ARG ALPINE_MIRROR_HOST=mirrors.aliyun.com
RUN sed -i "s/dl-cdn.alpinelinux.org/${ALPINE_MIRROR_HOST}/g" /etc/apk/repositories
COPY nginx.conf /etc/nginx/conf.d/default.conf COPY nginx.conf /etc/nginx/conf.d/default.conf
COPY --from=builder /app/dist /usr/share/nginx/html COPY --from=builder /app/dist /usr/share/nginx/html
EXPOSE 80 EXPOSE 80

View File

@@ -3,7 +3,7 @@
<head> <head>
<meta charset="UTF-8" /> <meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0, viewport-fit=cover" /> <meta name="viewport" content="width=device-width, initial-scale=1.0, viewport-fit=cover" />
<meta name="theme-color" content="#0b1223" /> <meta name="theme-color" content="#e8ecf1" />
<meta name="apple-mobile-web-app-capable" content="yes" /> <meta name="apple-mobile-web-app-capable" content="yes" />
<meta name="apple-mobile-web-app-status-bar-style" content="black-translucent" /> <meta name="apple-mobile-web-app-status-bar-style" content="black-translucent" />
<meta name="mobile-web-app-capable" content="yes" /> <meta name="mobile-web-app-capable" content="yes" />

1
frontend/node_modules/.bin/baseline-browser-mapping 2 generated vendored Symbolic link
View File

@@ -0,0 +1 @@
../baseline-browser-mapping/dist/cli.cjs

1
frontend/node_modules/.bin/browserslist 2 generated vendored Symbolic link
View File

@@ -0,0 +1 @@
../browserslist/cli.js

1
frontend/node_modules/.bin/esbuild 2 generated vendored Symbolic link
View File

@@ -0,0 +1 @@
../esbuild/bin/esbuild

1
frontend/node_modules/.bin/jsesc 2 generated vendored Symbolic link
View File

@@ -0,0 +1 @@
../jsesc/bin/jsesc

1
frontend/node_modules/.bin/json5 2 generated vendored Symbolic link
View File

@@ -0,0 +1 @@
../json5/lib/cli.js

1
frontend/node_modules/.bin/loose-envify 2 generated vendored Symbolic link
View File

@@ -0,0 +1 @@
../loose-envify/cli.js

1
frontend/node_modules/.bin/nanoid 2 generated vendored Symbolic link
View File

@@ -0,0 +1 @@
../nanoid/bin/nanoid.cjs

1
frontend/node_modules/.bin/parser 2 generated vendored Symbolic link
View File

@@ -0,0 +1 @@
../@babel/parser/bin/babel-parser.js

1
frontend/node_modules/.bin/rollup 2 generated vendored Symbolic link
View File

@@ -0,0 +1 @@
../rollup/dist/bin/rollup

1
frontend/node_modules/.bin/semver 2 generated vendored Symbolic link
View File

@@ -0,0 +1 @@
../semver/bin/semver.js

1
frontend/node_modules/.bin/update-browserslist-db 2 generated vendored Symbolic link
View File

@@ -0,0 +1 @@
../update-browserslist-db/cli.js

1
frontend/node_modules/.bin/vite 2 generated vendored Symbolic link
View File

@@ -0,0 +1 @@
../vite/bin/vite.js

View File

@@ -1002,6 +1002,21 @@
"node": ">= 6" "node": ">= 6"
} }
}, },
"node_modules/fsevents": {
"version": "2.3.3",
"resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz",
"integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==",
"dev": true,
"hasInstallScript": true,
"license": "MIT",
"optional": true,
"os": [
"darwin"
],
"engines": {
"node": "^8.16.0 || ^10.6.0 || >=11.0.0"
}
},
"node_modules/function-bind": { "node_modules/function-bind": {
"version": "1.1.2", "version": "1.1.2",
"resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz",

View File

@@ -0,0 +1,17 @@
{
"root": true,
"extends": "@ljharb",
"rules": {
"func-name-matching": 0,
"id-length": 0,
"new-cap": [2, {
"capIsNewExceptions": [
"GetIntrinsic",
],
}],
"no-extra-parens": 0,
"no-magic-numbers": 0,
},
}

View File

@@ -0,0 +1,9 @@
{
"all": true,
"check-coverage": false,
"reporter": ["text-summary", "text", "html", "json"],
"exclude": [
"coverage",
"test"
]
}

View File

@@ -0,0 +1,30 @@
# Changelog
All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/)
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
## [v1.0.2](https://github.com/ljharb/call-bind-apply-helpers/compare/v1.0.1...v1.0.2) - 2025-02-12
### Commits
- [types] improve inferred types [`e6f9586`](https://github.com/ljharb/call-bind-apply-helpers/commit/e6f95860a3c72879cb861a858cdfb8138fbedec1)
- [Dev Deps] update `@arethetypeswrong/cli`, `@ljharb/tsconfig`, `@types/tape`, `es-value-fixtures`, `for-each`, `has-strict-mode`, `object-inspect` [`e43d540`](https://github.com/ljharb/call-bind-apply-helpers/commit/e43d5409f97543bfbb11f345d47d8ce4e066d8c1)
## [v1.0.1](https://github.com/ljharb/call-bind-apply-helpers/compare/v1.0.0...v1.0.1) - 2024-12-08
### Commits
- [types] `reflectApply`: fix types [`4efc396`](https://github.com/ljharb/call-bind-apply-helpers/commit/4efc3965351a4f02cc55e836fa391d3d11ef2ef8)
- [Fix] `reflectApply`: oops, Reflect is not a function [`83cc739`](https://github.com/ljharb/call-bind-apply-helpers/commit/83cc7395de6b79b7730bdf092f1436f0b1263c75)
- [Dev Deps] update `@arethetypeswrong/cli` [`80bd5d3`](https://github.com/ljharb/call-bind-apply-helpers/commit/80bd5d3ae58b4f6b6995ce439dd5a1bcb178a940)
## v1.0.0 - 2024-12-05
### Commits
- Initial implementation, tests, readme [`7879629`](https://github.com/ljharb/call-bind-apply-helpers/commit/78796290f9b7430c9934d6f33d94ae9bc89fce04)
- Initial commit [`3f1dc16`](https://github.com/ljharb/call-bind-apply-helpers/commit/3f1dc164afc43285631b114a5f9dd9137b2b952f)
- npm init [`081df04`](https://github.com/ljharb/call-bind-apply-helpers/commit/081df048c312fcee400922026f6e97281200a603)
- Only apps should have lockfiles [`5b9ca0f`](https://github.com/ljharb/call-bind-apply-helpers/commit/5b9ca0fe8101ebfaf309c549caac4e0a017ed930)

View File

@@ -0,0 +1,21 @@
MIT License
Copyright (c) 2024 Jordan Harband
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

View File

@@ -0,0 +1,62 @@
# call-bind-apply-helpers <sup>[![Version Badge][npm-version-svg]][package-url]</sup>
[![github actions][actions-image]][actions-url]
[![coverage][codecov-image]][codecov-url]
[![dependency status][deps-svg]][deps-url]
[![dev dependency status][dev-deps-svg]][dev-deps-url]
[![License][license-image]][license-url]
[![Downloads][downloads-image]][downloads-url]
[![npm badge][npm-badge-png]][package-url]
Helper functions around Function call/apply/bind, for use in `call-bind`.
The only packages that should likely ever use this package directly are `call-bind` and `get-intrinsic`.
Please use `call-bind` unless you have a very good reason not to.
## Getting started
```sh
npm install --save call-bind-apply-helpers
```
## Usage/Examples
```js
const assert = require('assert');
const callBindBasic = require('call-bind-apply-helpers');
function f(a, b) {
assert.equal(this, 1);
assert.equal(a, 2);
assert.equal(b, 3);
assert.equal(arguments.length, 2);
}
const fBound = callBindBasic([f, 1]);
delete Function.prototype.call;
delete Function.prototype.bind;
fBound(2, 3);
```
## Tests
Clone the repo, `npm install`, and run `npm test`
[package-url]: https://npmjs.org/package/call-bind-apply-helpers
[npm-version-svg]: https://versionbadg.es/ljharb/call-bind-apply-helpers.svg
[deps-svg]: https://david-dm.org/ljharb/call-bind-apply-helpers.svg
[deps-url]: https://david-dm.org/ljharb/call-bind-apply-helpers
[dev-deps-svg]: https://david-dm.org/ljharb/call-bind-apply-helpers/dev-status.svg
[dev-deps-url]: https://david-dm.org/ljharb/call-bind-apply-helpers#info=devDependencies
[npm-badge-png]: https://nodei.co/npm/call-bind-apply-helpers.png?downloads=true&stars=true
[license-image]: https://img.shields.io/npm/l/call-bind-apply-helpers.svg
[license-url]: LICENSE
[downloads-image]: https://img.shields.io/npm/dm/call-bind-apply-helpers.svg
[downloads-url]: https://npm-stat.com/charts.html?package=call-bind-apply-helpers
[codecov-image]: https://codecov.io/gh/ljharb/call-bind-apply-helpers/branch/main/graphs/badge.svg
[codecov-url]: https://app.codecov.io/gh/ljharb/call-bind-apply-helpers/
[actions-image]: https://img.shields.io/endpoint?url=https://github-actions-badge-u3jn4tfpocch.runkit.sh/ljharb/call-bind-apply-helpers
[actions-url]: https://github.com/ljharb/call-bind-apply-helpers/actions

View File

@@ -0,0 +1,10 @@
'use strict';
var bind = require('function-bind');
var $apply = require('./functionApply');
var $call = require('./functionCall');
var $reflectApply = require('./reflectApply');
/** @type {import('./actualApply')} */
module.exports = $reflectApply || bind.call($call, $apply);

View File

@@ -0,0 +1 @@
export = Reflect.apply;

View File

@@ -0,0 +1,10 @@
'use strict';
var bind = require('function-bind');
var $apply = require('./functionApply');
var actualApply = require('./actualApply');
/** @type {import('./applyBind')} */
module.exports = function applyBind() {
return actualApply(bind, $apply, arguments);
};

View File

@@ -0,0 +1,19 @@
import actualApply from './actualApply';
type TupleSplitHead<T extends any[], N extends number> = T['length'] extends N
? T
: T extends [...infer R, any]
? TupleSplitHead<R, N>
: never
type TupleSplitTail<T, N extends number, O extends any[] = []> = O['length'] extends N
? T
: T extends [infer F, ...infer R]
? TupleSplitTail<[...R], N, [...O, F]>
: never
type TupleSplit<T extends any[], N extends number> = [TupleSplitHead<T, N>, TupleSplitTail<T, N>]
declare function applyBind(...args: TupleSplit<Parameters<typeof actualApply>, 2>[1]): ReturnType<typeof actualApply>;
export = applyBind;

View File

@@ -0,0 +1,4 @@
'use strict';
/** @type {import('./functionApply')} */
module.exports = Function.prototype.apply;

View File

@@ -0,0 +1 @@
export = Function.prototype.apply;

View File

@@ -0,0 +1,4 @@
'use strict';
/** @type {import('./functionCall')} */
module.exports = Function.prototype.call;

View File

@@ -0,0 +1 @@
export = Function.prototype.call;

View File

@@ -0,0 +1,15 @@
'use strict';
var bind = require('function-bind');
var $TypeError = require('es-errors/type');
var $call = require('./functionCall');
var $actualApply = require('./actualApply');
/** @type {(args: [Function, thisArg?: unknown, ...args: unknown[]]) => Function} TODO FIXME, find a way to use import('.') */
module.exports = function callBindBasic(args) {
if (args.length < 1 || typeof args[0] !== 'function') {
throw new $TypeError('a function is required');
}
return $actualApply(bind, $call, args);
};

View File

@@ -0,0 +1,64 @@
type RemoveFromTuple<
Tuple extends readonly unknown[],
RemoveCount extends number,
Index extends 1[] = []
> = Index["length"] extends RemoveCount
? Tuple
: Tuple extends [infer First, ...infer Rest]
? RemoveFromTuple<Rest, RemoveCount, [...Index, 1]>
: Tuple;
type ConcatTuples<
Prefix extends readonly unknown[],
Suffix extends readonly unknown[]
> = [...Prefix, ...Suffix];
type ExtractFunctionParams<T> = T extends (this: infer TThis, ...args: infer P extends readonly unknown[]) => infer R
? { thisArg: TThis; params: P; returnType: R }
: never;
type BindFunction<
T extends (this: any, ...args: any[]) => any,
TThis,
TBoundArgs extends readonly unknown[],
ReceiverBound extends boolean
> = ExtractFunctionParams<T> extends {
thisArg: infer OrigThis;
params: infer P extends readonly unknown[];
returnType: infer R;
}
? ReceiverBound extends true
? (...args: RemoveFromTuple<P, Extract<TBoundArgs["length"], number>>) => R extends [OrigThis, ...infer Rest]
? [TThis, ...Rest] // Replace `this` with `thisArg`
: R
: <U, RemainingArgs extends RemoveFromTuple<P, Extract<TBoundArgs["length"], number>>>(
thisArg: U,
...args: RemainingArgs
) => R extends [OrigThis, ...infer Rest]
? [U, ...ConcatTuples<TBoundArgs, Rest>] // Preserve bound args in return type
: R
: never;
declare function callBind<
const T extends (this: any, ...args: any[]) => any,
Extracted extends ExtractFunctionParams<T>,
const TBoundArgs extends Partial<Extracted["params"]> & readonly unknown[],
const TThis extends Extracted["thisArg"]
>(
args: [fn: T, thisArg: TThis, ...boundArgs: TBoundArgs]
): BindFunction<T, TThis, TBoundArgs, true>;
declare function callBind<
const T extends (this: any, ...args: any[]) => any,
Extracted extends ExtractFunctionParams<T>,
const TBoundArgs extends Partial<Extracted["params"]> & readonly unknown[]
>(
args: [fn: T, ...boundArgs: TBoundArgs]
): BindFunction<T, Extracted["thisArg"], TBoundArgs, false>;
declare function callBind<const TArgs extends readonly unknown[]>(
args: [fn: Exclude<TArgs[0], Function>, ...rest: TArgs]
): never;
// export as namespace callBind;
export = callBind;

View File

@@ -0,0 +1,85 @@
{
"name": "call-bind-apply-helpers",
"version": "1.0.2",
"description": "Helper functions around Function call/apply/bind, for use in `call-bind`",
"main": "index.js",
"exports": {
".": "./index.js",
"./actualApply": "./actualApply.js",
"./applyBind": "./applyBind.js",
"./functionApply": "./functionApply.js",
"./functionCall": "./functionCall.js",
"./reflectApply": "./reflectApply.js",
"./package.json": "./package.json"
},
"scripts": {
"prepack": "npmignore --auto --commentLines=auto",
"prepublish": "not-in-publish || npm run prepublishOnly",
"prepublishOnly": "safe-publish-latest",
"prelint": "evalmd README.md",
"lint": "eslint --ext=.js,.mjs .",
"postlint": "tsc -p . && attw -P",
"pretest": "npm run lint",
"tests-only": "nyc tape 'test/**/*.js'",
"test": "npm run tests-only",
"posttest": "npx npm@'>=10.2' audit --production",
"version": "auto-changelog && git add CHANGELOG.md",
"postversion": "auto-changelog && git add CHANGELOG.md && git commit --no-edit --amend && git tag -f \"v$(node -e \"console.log(require('./package.json').version)\")\""
},
"repository": {
"type": "git",
"url": "git+https://github.com/ljharb/call-bind-apply-helpers.git"
},
"author": "Jordan Harband <ljharb@gmail.com>",
"license": "MIT",
"bugs": {
"url": "https://github.com/ljharb/call-bind-apply-helpers/issues"
},
"homepage": "https://github.com/ljharb/call-bind-apply-helpers#readme",
"dependencies": {
"es-errors": "^1.3.0",
"function-bind": "^1.1.2"
},
"devDependencies": {
"@arethetypeswrong/cli": "^0.17.3",
"@ljharb/eslint-config": "^21.1.1",
"@ljharb/tsconfig": "^0.2.3",
"@types/for-each": "^0.3.3",
"@types/function-bind": "^1.1.10",
"@types/object-inspect": "^1.13.0",
"@types/tape": "^5.8.1",
"auto-changelog": "^2.5.0",
"encoding": "^0.1.13",
"es-value-fixtures": "^1.7.1",
"eslint": "=8.8.0",
"evalmd": "^0.0.19",
"for-each": "^0.3.5",
"has-strict-mode": "^1.1.0",
"in-publish": "^2.0.1",
"npmignore": "^0.3.1",
"nyc": "^10.3.2",
"object-inspect": "^1.13.4",
"safe-publish-latest": "^2.0.0",
"tape": "^5.9.0",
"typescript": "next"
},
"testling": {
"files": "test/index.js"
},
"auto-changelog": {
"output": "CHANGELOG.md",
"template": "keepachangelog",
"unreleased": false,
"commitLimit": false,
"backfillLimit": false,
"hideCredit": true
},
"publishConfig": {
"ignore": [
".github/workflows"
]
},
"engines": {
"node": ">= 0.4"
}
}

View File

@@ -0,0 +1,4 @@
'use strict';
/** @type {import('./reflectApply')} */
module.exports = typeof Reflect !== 'undefined' && Reflect && Reflect.apply;

View File

@@ -0,0 +1,3 @@
declare const reflectApply: false | typeof Reflect.apply;
export = reflectApply;

View File

@@ -0,0 +1,9 @@
{
"extends": "@ljharb/tsconfig",
"compilerOptions": {
"target": "es2021",
},
"exclude": [
"coverage",
],
}

395
frontend/node_modules/caniuse-lite/LICENSE 2 generated vendored Normal file
View File

@@ -0,0 +1,395 @@
Attribution 4.0 International
=======================================================================
Creative Commons Corporation ("Creative Commons") is not a law firm and
does not provide legal services or legal advice. Distribution of
Creative Commons public licenses does not create a lawyer-client or
other relationship. Creative Commons makes its licenses and related
information available on an "as-is" basis. Creative Commons gives no
warranties regarding its licenses, any material licensed under their
terms and conditions, or any related information. Creative Commons
disclaims all liability for damages resulting from their use to the
fullest extent possible.
Using Creative Commons Public Licenses
Creative Commons public licenses provide a standard set of terms and
conditions that creators and other rights holders may use to share
original works of authorship and other material subject to copyright
and certain other rights specified in the public license below. The
following considerations are for informational purposes only, are not
exhaustive, and do not form part of our licenses.
Considerations for licensors: Our public licenses are
intended for use by those authorized to give the public
permission to use material in ways otherwise restricted by
copyright and certain other rights. Our licenses are
irrevocable. Licensors should read and understand the terms
and conditions of the license they choose before applying it.
Licensors should also secure all rights necessary before
applying our licenses so that the public can reuse the
material as expected. Licensors should clearly mark any
material not subject to the license. This includes other CC-
licensed material, or material used under an exception or
limitation to copyright. More considerations for licensors:
wiki.creativecommons.org/Considerations_for_licensors
Considerations for the public: By using one of our public
licenses, a licensor grants the public permission to use the
licensed material under specified terms and conditions. If
the licensor's permission is not necessary for any reason--for
example, because of any applicable exception or limitation to
copyright--then that use is not regulated by the license. Our
licenses grant only permissions under copyright and certain
other rights that a licensor has authority to grant. Use of
the licensed material may still be restricted for other
reasons, including because others have copyright or other
rights in the material. A licensor may make special requests,
such as asking that all changes be marked or described.
Although not required by our licenses, you are encouraged to
respect those requests where reasonable. More_considerations
for the public:
wiki.creativecommons.org/Considerations_for_licensees
=======================================================================
Creative Commons Attribution 4.0 International Public License
By exercising the Licensed Rights (defined below), You accept and agree
to be bound by the terms and conditions of this Creative Commons
Attribution 4.0 International Public License ("Public License"). To the
extent this Public License may be interpreted as a contract, You are
granted the Licensed Rights in consideration of Your acceptance of
these terms and conditions, and the Licensor grants You such rights in
consideration of benefits the Licensor receives from making the
Licensed Material available under these terms and conditions.
Section 1 -- Definitions.
a. Adapted Material means material subject to Copyright and Similar
Rights that is derived from or based upon the Licensed Material
and in which the Licensed Material is translated, altered,
arranged, transformed, or otherwise modified in a manner requiring
permission under the Copyright and Similar Rights held by the
Licensor. For purposes of this Public License, where the Licensed
Material is a musical work, performance, or sound recording,
Adapted Material is always produced where the Licensed Material is
synched in timed relation with a moving image.
b. Adapter's License means the license You apply to Your Copyright
and Similar Rights in Your contributions to Adapted Material in
accordance with the terms and conditions of this Public License.
c. Copyright and Similar Rights means copyright and/or similar rights
closely related to copyright including, without limitation,
performance, broadcast, sound recording, and Sui Generis Database
Rights, without regard to how the rights are labeled or
categorized. For purposes of this Public License, the rights
specified in Section 2(b)(1)-(2) are not Copyright and Similar
Rights.
d. Effective Technological Measures means those measures that, in the
absence of proper authority, may not be circumvented under laws
fulfilling obligations under Article 11 of the WIPO Copyright
Treaty adopted on December 20, 1996, and/or similar international
agreements.
e. Exceptions and Limitations means fair use, fair dealing, and/or
any other exception or limitation to Copyright and Similar Rights
that applies to Your use of the Licensed Material.
f. Licensed Material means the artistic or literary work, database,
or other material to which the Licensor applied this Public
License.
g. Licensed Rights means the rights granted to You subject to the
terms and conditions of this Public License, which are limited to
all Copyright and Similar Rights that apply to Your use of the
Licensed Material and that the Licensor has authority to license.
h. Licensor means the individual(s) or entity(ies) granting rights
under this Public License.
i. Share means to provide material to the public by any means or
process that requires permission under the Licensed Rights, such
as reproduction, public display, public performance, distribution,
dissemination, communication, or importation, and to make material
available to the public including in ways that members of the
public may access the material from a place and at a time
individually chosen by them.
j. Sui Generis Database Rights means rights other than copyright
resulting from Directive 96/9/EC of the European Parliament and of
the Council of 11 March 1996 on the legal protection of databases,
as amended and/or succeeded, as well as other essentially
equivalent rights anywhere in the world.
k. You means the individual or entity exercising the Licensed Rights
under this Public License. Your has a corresponding meaning.
Section 2 -- Scope.
a. License grant.
1. Subject to the terms and conditions of this Public License,
the Licensor hereby grants You a worldwide, royalty-free,
non-sublicensable, non-exclusive, irrevocable license to
exercise the Licensed Rights in the Licensed Material to:
a. reproduce and Share the Licensed Material, in whole or
in part; and
b. produce, reproduce, and Share Adapted Material.
2. Exceptions and Limitations. For the avoidance of doubt, where
Exceptions and Limitations apply to Your use, this Public
License does not apply, and You do not need to comply with
its terms and conditions.
3. Term. The term of this Public License is specified in Section
6(a).
4. Media and formats; technical modifications allowed. The
Licensor authorizes You to exercise the Licensed Rights in
all media and formats whether now known or hereafter created,
and to make technical modifications necessary to do so. The
Licensor waives and/or agrees not to assert any right or
authority to forbid You from making technical modifications
necessary to exercise the Licensed Rights, including
technical modifications necessary to circumvent Effective
Technological Measures. For purposes of this Public License,
simply making modifications authorized by this Section 2(a)
(4) never produces Adapted Material.
5. Downstream recipients.
a. Offer from the Licensor -- Licensed Material. Every
recipient of the Licensed Material automatically
receives an offer from the Licensor to exercise the
Licensed Rights under the terms and conditions of this
Public License.
b. No downstream restrictions. You may not offer or impose
any additional or different terms or conditions on, or
apply any Effective Technological Measures to, the
Licensed Material if doing so restricts exercise of the
Licensed Rights by any recipient of the Licensed
Material.
6. No endorsement. Nothing in this Public License constitutes or
may be construed as permission to assert or imply that You
are, or that Your use of the Licensed Material is, connected
with, or sponsored, endorsed, or granted official status by,
the Licensor or others designated to receive attribution as
provided in Section 3(a)(1)(A)(i).
b. Other rights.
1. Moral rights, such as the right of integrity, are not
licensed under this Public License, nor are publicity,
privacy, and/or other similar personality rights; however, to
the extent possible, the Licensor waives and/or agrees not to
assert any such rights held by the Licensor to the limited
extent necessary to allow You to exercise the Licensed
Rights, but not otherwise.
2. Patent and trademark rights are not licensed under this
Public License.
3. To the extent possible, the Licensor waives any right to
collect royalties from You for the exercise of the Licensed
Rights, whether directly or through a collecting society
under any voluntary or waivable statutory or compulsory
licensing scheme. In all other cases the Licensor expressly
reserves any right to collect such royalties.
Section 3 -- License Conditions.
Your exercise of the Licensed Rights is expressly made subject to the
following conditions.
a. Attribution.
1. If You Share the Licensed Material (including in modified
form), You must:
a. retain the following if it is supplied by the Licensor
with the Licensed Material:
i. identification of the creator(s) of the Licensed
Material and any others designated to receive
attribution, in any reasonable manner requested by
the Licensor (including by pseudonym if
designated);
ii. a copyright notice;
iii. a notice that refers to this Public License;
iv. a notice that refers to the disclaimer of
warranties;
v. a URI or hyperlink to the Licensed Material to the
extent reasonably practicable;
b. indicate if You modified the Licensed Material and
retain an indication of any previous modifications; and
c. indicate the Licensed Material is licensed under this
Public License, and include the text of, or the URI or
hyperlink to, this Public License.
2. You may satisfy the conditions in Section 3(a)(1) in any
reasonable manner based on the medium, means, and context in
which You Share the Licensed Material. For example, it may be
reasonable to satisfy the conditions by providing a URI or
hyperlink to a resource that includes the required
information.
3. If requested by the Licensor, You must remove any of the
information required by Section 3(a)(1)(A) to the extent
reasonably practicable.
4. If You Share Adapted Material You produce, the Adapter's
License You apply must not prevent recipients of the Adapted
Material from complying with this Public License.
Section 4 -- Sui Generis Database Rights.
Where the Licensed Rights include Sui Generis Database Rights that
apply to Your use of the Licensed Material:
a. for the avoidance of doubt, Section 2(a)(1) grants You the right
to extract, reuse, reproduce, and Share all or a substantial
portion of the contents of the database;
b. if You include all or a substantial portion of the database
contents in a database in which You have Sui Generis Database
Rights, then the database in which You have Sui Generis Database
Rights (but not its individual contents) is Adapted Material; and
c. You must comply with the conditions in Section 3(a) if You Share
all or a substantial portion of the contents of the database.
For the avoidance of doubt, this Section 4 supplements and does not
replace Your obligations under this Public License where the Licensed
Rights include other Copyright and Similar Rights.
Section 5 -- Disclaimer of Warranties and Limitation of Liability.
a. UNLESS OTHERWISE SEPARATELY UNDERTAKEN BY THE LICENSOR, TO THE
EXTENT POSSIBLE, THE LICENSOR OFFERS THE LICENSED MATERIAL AS-IS
AND AS-AVAILABLE, AND MAKES NO REPRESENTATIONS OR WARRANTIES OF
ANY KIND CONCERNING THE LICENSED MATERIAL, WHETHER EXPRESS,
IMPLIED, STATUTORY, OR OTHER. THIS INCLUDES, WITHOUT LIMITATION,
WARRANTIES OF TITLE, MERCHANTABILITY, FITNESS FOR A PARTICULAR
PURPOSE, NON-INFRINGEMENT, ABSENCE OF LATENT OR OTHER DEFECTS,
ACCURACY, OR THE PRESENCE OR ABSENCE OF ERRORS, WHETHER OR NOT
KNOWN OR DISCOVERABLE. WHERE DISCLAIMERS OF WARRANTIES ARE NOT
ALLOWED IN FULL OR IN PART, THIS DISCLAIMER MAY NOT APPLY TO YOU.
b. TO THE EXTENT POSSIBLE, IN NO EVENT WILL THE LICENSOR BE LIABLE
TO YOU ON ANY LEGAL THEORY (INCLUDING, WITHOUT LIMITATION,
NEGLIGENCE) OR OTHERWISE FOR ANY DIRECT, SPECIAL, INDIRECT,
INCIDENTAL, CONSEQUENTIAL, PUNITIVE, EXEMPLARY, OR OTHER LOSSES,
COSTS, EXPENSES, OR DAMAGES ARISING OUT OF THIS PUBLIC LICENSE OR
USE OF THE LICENSED MATERIAL, EVEN IF THE LICENSOR HAS BEEN
ADVISED OF THE POSSIBILITY OF SUCH LOSSES, COSTS, EXPENSES, OR
DAMAGES. WHERE A LIMITATION OF LIABILITY IS NOT ALLOWED IN FULL OR
IN PART, THIS LIMITATION MAY NOT APPLY TO YOU.
c. The disclaimer of warranties and limitation of liability provided
above shall be interpreted in a manner that, to the extent
possible, most closely approximates an absolute disclaimer and
waiver of all liability.
Section 6 -- Term and Termination.
a. This Public License applies for the term of the Copyright and
Similar Rights licensed here. However, if You fail to comply with
this Public License, then Your rights under this Public License
terminate automatically.
b. Where Your right to use the Licensed Material has terminated under
Section 6(a), it reinstates:
1. automatically as of the date the violation is cured, provided
it is cured within 30 days of Your discovery of the
violation; or
2. upon express reinstatement by the Licensor.
For the avoidance of doubt, this Section 6(b) does not affect any
right the Licensor may have to seek remedies for Your violations
of this Public License.
c. For the avoidance of doubt, the Licensor may also offer the
Licensed Material under separate terms or conditions or stop
distributing the Licensed Material at any time; however, doing so
will not terminate this Public License.
d. Sections 1, 5, 6, 7, and 8 survive termination of this Public
License.
Section 7 -- Other Terms and Conditions.
a. The Licensor shall not be bound by any additional or different
terms or conditions communicated by You unless expressly agreed.
b. Any arrangements, understandings, or agreements regarding the
Licensed Material not stated herein are separate from and
independent of the terms and conditions of this Public License.
Section 8 -- Interpretation.
a. For the avoidance of doubt, this Public License does not, and
shall not be interpreted to, reduce, limit, restrict, or impose
conditions on any use of the Licensed Material that could lawfully
be made without permission under this Public License.
b. To the extent possible, if any provision of this Public License is
deemed unenforceable, it shall be automatically reformed to the
minimum extent necessary to make it enforceable. If the provision
cannot be reformed, it shall be severed from this Public License
without affecting the enforceability of the remaining terms and
conditions.
c. No term or condition of this Public License will be waived and no
failure to comply consented to unless expressly agreed to by the
Licensor.
d. Nothing in this Public License constitutes or may be interpreted
as a limitation upon, or waiver of, any privileges and immunities
that apply to the Licensor or You, including from the legal
processes of any jurisdiction or authority.
=======================================================================
Creative Commons is not a party to its public
licenses. Notwithstanding, Creative Commons may elect to apply one of
its public licenses to material it publishes and in those instances
will be considered the “Licensor.” The text of the Creative Commons
public licenses is dedicated to the public domain under the CC0 Public
Domain Dedication. Except for the limited purpose of indicating that
material is shared under a Creative Commons public license or as
otherwise permitted by the Creative Commons policies published at
creativecommons.org/policies, Creative Commons does not authorize the
use of the trademark "Creative Commons" or any other trademark or logo
of Creative Commons without its prior written consent including,
without limitation, in connection with any unauthorized modifications
to any of its public licenses or any other arrangements,
understandings, or agreements concerning use of licensed material. For
the avoidance of doubt, this paragraph does not form part of the
public licenses.
Creative Commons may be contacted at creativecommons.org.

6
frontend/node_modules/caniuse-lite/README 2.md generated vendored Normal file
View File

@@ -0,0 +1,6 @@
# caniuse-lite
A smaller version of caniuse-db, with only the essentials!
## Docs
Read full docs **[here](https://github.com/browserslist/caniuse-lite#readme)**.

34
frontend/node_modules/caniuse-lite/package 2.json generated vendored Normal file
View File

@@ -0,0 +1,34 @@
{
"name": "caniuse-lite",
"version": "1.0.30001781",
"description": "A smaller version of caniuse-db, with only the essentials!",
"main": "dist/unpacker/index.js",
"files": [
"data",
"dist"
],
"keywords": [
"support"
],
"author": {
"name": "Ben Briggs",
"email": "beneb.info@gmail.com",
"url": "http://beneb.info"
},
"repository": "browserslist/caniuse-lite",
"funding": [
{
"type": "opencollective",
"url": "https://opencollective.com/browserslist"
},
{
"type": "tidelift",
"url": "https://tidelift.com/funding/github/npm/caniuse-lite"
},
{
"type": "github",
"url": "https://github.com/sponsors/ai"
}
],
"license": "CC-BY-4.0"
}

19
frontend/node_modules/csstype/LICENSE 2 generated vendored Normal file
View File

@@ -0,0 +1,19 @@
Copyright (c) 2017-2018 Fredrik Nicol
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

291
frontend/node_modules/csstype/README 2.md generated vendored Normal file
View File

@@ -0,0 +1,291 @@
# CSSType
[![npm](https://img.shields.io/npm/v/csstype.svg)](https://www.npmjs.com/package/csstype)
TypeScript and Flow definitions for CSS, generated by [data from MDN](https://github.com/mdn/data). It provides autocompletion and type checking for CSS properties and values.
**TypeScript**
```ts
import type * as CSS from 'csstype';
const style: CSS.Properties = {
colour: 'white', // Type error on property
textAlign: 'middle', // Type error on value
};
```
**Flow**
```js
// @flow strict
import * as CSS from 'csstype';
const style: CSS.Properties<> = {
colour: 'white', // Type error on property
textAlign: 'middle', // Type error on value
};
```
_Further examples below will be in TypeScript!_
## Getting started
```sh
$ npm install csstype
```
## Table of content
- [Style types](#style-types)
- [At-rule types](#at-rule-types)
- [Pseudo types](#pseudo-types)
- [Generics](#generics)
- [Usage](#usage)
- [What should I do when I get type errors?](#what-should-i-do-when-i-get-type-errors)
- [Version 3.0](#version-30)
- [Contributing](#contributing)
## Style types
Properties are categorized in different uses and in several technical variations to provide typings that suits as many as possible.
| | Default | `Hyphen` | `Fallback` | `HyphenFallback` |
| -------------- | -------------------- | -------------------------- | ---------------------------- | ---------------------------------- |
| **All** | `Properties` | `PropertiesHyphen` | `PropertiesFallback` | `PropertiesHyphenFallback` |
| **`Standard`** | `StandardProperties` | `StandardPropertiesHyphen` | `StandardPropertiesFallback` | `StandardPropertiesHyphenFallback` |
| **`Vendor`** | `VendorProperties` | `VendorPropertiesHyphen` | `VendorPropertiesFallback` | `VendorPropertiesHyphenFallback` |
| **`Obsolete`** | `ObsoleteProperties` | `ObsoletePropertiesHyphen` | `ObsoletePropertiesFallback` | `ObsoletePropertiesHyphenFallback` |
| **`Svg`** | `SvgProperties` | `SvgPropertiesHyphen` | `SvgPropertiesFallback` | `SvgPropertiesHyphenFallback` |
Categories:
- **All** - Includes `Standard`, `Vendor`, `Obsolete` and `Svg`
- **`Standard`** - Current properties and extends subcategories `StandardLonghand` and `StandardShorthand` _(e.g. `StandardShorthandProperties`)_
- **`Vendor`** - Vendor prefixed properties and extends subcategories `VendorLonghand` and `VendorShorthand` _(e.g. `VendorShorthandProperties`)_
- **`Obsolete`** - Removed or deprecated properties
- **`Svg`** - SVG-specific properties
Variations:
- **Default** - JavaScript (camel) cased property names
- **`Hyphen`** - CSS (kebab) cased property names
- **`Fallback`** - Also accepts array of values e.g. `string | string[]`
## At-rule types
At-rule interfaces with descriptors.
**TypeScript**: These will be found in the `AtRule` namespace, e.g. `AtRule.Viewport`.
**Flow**: These will be prefixed with `AtRule$`, e.g. `AtRule$Viewport`.
| | Default | `Hyphen` | `Fallback` | `HyphenFallback` |
| -------------------- | -------------- | -------------------- | ---------------------- | ---------------------------- |
| **`@counter-style`** | `CounterStyle` | `CounterStyleHyphen` | `CounterStyleFallback` | `CounterStyleHyphenFallback` |
| **`@font-face`** | `FontFace` | `FontFaceHyphen` | `FontFaceFallback` | `FontFaceHyphenFallback` |
| **`@viewport`** | `Viewport` | `ViewportHyphen` | `ViewportFallback` | `ViewportHyphenFallback` |
## Pseudo types
String literals of pseudo classes and pseudo elements
- `Pseudos`
Extends:
- `AdvancedPseudos`
Function-like pseudos e.g. `:not(:first-child)`. The string literal contains the value excluding the parenthesis: `:not`. These are separated because they require an argument that results in infinite number of variations.
- `SimplePseudos`
Plain pseudos e.g. `:hover` that can only be **one** variation.
## Generics
All interfaces has two optional generic argument to define length and time: `CSS.Properties<TLength = string | 0, TTime = string>`
- **Length** is the first generic parameter and defaults to `string | 0` because `0` is the only [length where the unit identifier is optional](https://drafts.csswg.org/css-values-3/#lengths). You can specify this, e.g. `string | number`, for platforms and libraries that accepts any numeric value as length with a specific unit.
```tsx
const style: CSS.Properties<string | number> = {
width: 100,
};
```
- **Time** is the second generic argument and defaults to `string`. You can specify this, e.g. `string | number`, for platforms and libraries that accepts any numeric value as length with a specific unit.
```tsx
const style: CSS.Properties<string | number, number> = {
transitionDuration: 1000,
};
```
## Usage
```ts
import type * as CSS from 'csstype';
const style: CSS.Properties = {
width: '10px',
margin: '1em',
};
```
In some cases, like for CSS-in-JS libraries, an array of values is a way to provide fallback values in CSS. Using `CSS.PropertiesFallback` instead of `CSS.Properties` will add the possibility to use any property value as an array of values.
```ts
import type * as CSS from 'csstype';
const style: CSS.PropertiesFallback = {
display: ['-webkit-flex', 'flex'],
color: 'white',
};
```
There's even string literals for pseudo selectors and elements.
```ts
import type * as CSS from 'csstype';
const pseudos: { [P in CSS.SimplePseudos]?: CSS.Properties } = {
':hover': {
display: 'flex',
},
};
```
Hyphen cased (kebab cased) properties are provided in `CSS.PropertiesHyphen` and `CSS.PropertiesHyphenFallback`. It's not **not** added by default in `CSS.Properties`. To allow both of them, you can simply extend with `CSS.PropertiesHyphen` or/and `CSS.PropertiesHyphenFallback`.
```ts
import type * as CSS from 'csstype';
interface Style extends CSS.Properties, CSS.PropertiesHyphen {}
const style: Style = {
'flex-grow': 1,
'flex-shrink': 0,
'font-weight': 'normal',
backgroundColor: 'white',
};
```
Adding type checked CSS properties to a `HTMLElement`.
```ts
import type * as CSS from 'csstype';
const style: CSS.Properties = {
color: 'red',
margin: '1em',
};
let button = document.createElement('button');
Object.assign(button.style, style);
```
## What should I do when I get type errors?
The goal is to have as perfect types as possible and we're trying to do our best. But with CSS Custom Properties, the CSS specification changing frequently and vendors implementing their own specifications with new releases sometimes causes type errors even if it should work. Here's some steps you could take to get it fixed:
_If you're using CSS Custom Properties you can step directly to step 3._
1. **First of all, make sure you're doing it right.** A type error could also indicate that you're not :wink:
- Some CSS specs that some vendors has implemented could have been officially rejected or haven't yet received any official acceptance and are therefor not included
- If you're using TypeScript, [type widening](https://blog.mariusschulz.com/2017/02/04/TypeScript-2-1-literal-type-widening) could be the reason you get `Type 'string' is not assignable to...` errors
2. **Have a look in [issues](https://github.com/frenic/csstype/issues) to see if an issue already has been filed. If not, create a new one.** To help us out, please refer to any information you have found.
3. Fix the issue locally with **TypeScript** (Flow further down):
- The recommended way is to use **module augmentation**. Here's a few examples:
```ts
// My css.d.ts file
import type * as CSS from 'csstype';
declare module 'csstype' {
interface Properties {
// Add a missing property
WebkitRocketLauncher?: string;
// Add a CSS Custom Property
'--theme-color'?: 'black' | 'white';
// Allow namespaced CSS Custom Properties
[index: `--theme-${string}`]: any;
// Allow any CSS Custom Properties
[index: `--${string}`]: any;
// ...or allow any other property
[index: string]: any;
}
}
```
- The alternative way is to use **type assertion**. Here's a few examples:
```ts
const style: CSS.Properties = {
// Add a missing property
['WebkitRocketLauncher' as any]: 'launching',
// Add a CSS Custom Property
['--theme-color' as any]: 'black',
};
```
Fix the issue locally with **Flow**:
- Use **type assertion**. Here's a few examples:
```js
const style: $Exact<CSS.Properties<*>> = {
// Add a missing property
[('WebkitRocketLauncher': any)]: 'launching',
// Add a CSS Custom Property
[('--theme-color': any)]: 'black',
};
```
## Version 3.2
- **No longer compatible with version 2**
Conflicts may occur when both version ^3.2.0 and ^2.0.0 are installed. Potential fix for Npm would be to force resolution in `package.json`:
```json
{
"overrides": {
"csstype": "^3.2.0"
}
}
```
## Version 3.1
- **Data types are exposed**
TypeScript: `DataType.Color`
Flow: `DataType$Color`
## Version 3.0
- **All property types are exposed with namespace**
TypeScript: `Property.AlignContent` (was `AlignContentProperty` before)
Flow: `Property$AlignContent`
- **All at-rules are exposed with namespace**
TypeScript: `AtRule.FontFace` (was `FontFace` before)
Flow: `AtRule$FontFace`
- **Data types are NOT exposed**
E.g. `Color` and `Box`. Because the generation of data types may suddenly be removed or renamed.
- **TypeScript hack for autocompletion**
Uses `(string & {})` for literal string unions and `(number & {})` for literal number unions ([related issue](https://github.com/microsoft/TypeScript/issues/29729)). Utilize `PropertyValue<T>` to unpack types from e.g. `(string & {})` to `string`.
- **New generic for time**
Read more on the ["Generics"](#generics) section.
- **Flow types improvements**
Flow Strict enabled and exact types are used.
## Contributing
**Never modify `index.d.ts` and `index.js.flow` directly. They are generated automatically and committed so that we can easily follow any change it results in.** Therefor it's important that you run `$ git config merge.ours.driver true` after you've forked and cloned. That setting prevents merge conflicts when doing rebase.
### Commands
- `npm run build` Generates typings and type checks them
- `npm run watch` Runs build on each save
- `npm run test` Runs the tests
- `npm run lazy` Type checks, lints and formats everything

22569
frontend/node_modules/csstype/index.d 2.ts generated vendored Normal file

File diff suppressed because it is too large Load Diff

6863
frontend/node_modules/csstype/index.js 2.flow generated vendored Normal file

File diff suppressed because it is too large Load Diff

70
frontend/node_modules/csstype/package 2.json generated vendored Normal file
View File

@@ -0,0 +1,70 @@
{
"name": "csstype",
"version": "3.2.3",
"main": "",
"types": "index.d.ts",
"description": "Strict TypeScript and Flow types for style based on MDN data",
"repository": "https://github.com/frenic/csstype",
"author": "Fredrik Nicol <fredrik.nicol@gmail.com>",
"license": "MIT",
"devDependencies": {
"@babel/core": "^7.28.5",
"@babel/preset-env": "^7.28.5",
"@babel/preset-typescript": "^7.28.5",
"@eslint/js": "^9.39.1",
"@mdn/browser-compat-data": "7.1.21",
"@tsconfig/node24": "^24.0.2",
"@types/chokidar": "^2.1.7",
"@types/css-tree": "^2.3.11",
"@types/jest": "^30.0.0",
"@types/jsdom": "^27.0.0",
"@types/node": "^24.10.1",
"@types/prettier": "^3.0.0",
"@types/turndown": "^5.0.6",
"babel-jest": "^30.2.0",
"chalk": "^5.6.2",
"chokidar": "^4.0.3",
"css-tree": "^3.1.0",
"eslint-config-prettier": "^10.1.8",
"eslint-plugin-prettier": "^5.5.4",
"flow-bin": "^0.291.0",
"jest": "^30.2.0",
"jsdom": "^27.2.0",
"mdn-data": "2.25.0",
"prettier": "^3.6.2",
"release-it": "^19.0.6",
"tsx": "^4.20.6",
"turndown": "^7.2.2",
"typescript": "~5.9.3",
"typescript-eslint": "^8.46.4"
},
"overrides": {
"js-yaml": ">=4.1.1"
},
"scripts": {
"prepublish": "npm install --no-save --prefix __tests__ && npm install --no-save --prefix __tests__/__fixtures__",
"release": "release-it",
"update": "tsx update.ts",
"build": "tsx --inspect build.ts --start",
"watch": "tsx build.ts --watch",
"lint": "eslint . --ext .js,.jsx,.ts,.tsx --fix",
"pretty": "prettier --write build.ts **/*.{ts,js,json,md}",
"lazy": "tsc && npm run lint",
"test": "jest --runInBand",
"test:src": "jest src.*.ts",
"test:dist": "jest dist.*.ts --runInBand"
},
"files": [
"index.d.ts",
"index.js.flow"
],
"keywords": [
"css",
"style",
"typescript",
"flow",
"typings",
"types",
"definitions"
]
}

13
frontend/node_modules/d3-color/LICENSE 2 generated vendored Normal file
View File

@@ -0,0 +1,13 @@
Copyright 2010-2022 Mike Bostock
Permission to use, copy, modify, and/or distribute this software for any purpose
with or without fee is hereby granted, provided that the above copyright notice
and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
THIS SOFTWARE.

203
frontend/node_modules/d3-color/README 2.md generated vendored Normal file
View File

@@ -0,0 +1,203 @@
# d3-color
Even though your browser understands a lot about colors, it doesnt offer much help in manipulating colors through JavaScript. The d3-color module therefore provides representations for various color spaces, allowing specification, conversion and manipulation. (Also see [d3-interpolate](https://github.com/d3/d3-interpolate) for color interpolation.)
For example, take the color named “steelblue”:
```js
const c = d3.color("steelblue"); // {r: 70, g: 130, b: 180, opacity: 1}
```
Lets try converting it to HSL:
```js
const c = d3.hsl("steelblue"); // {h: 207.27…, s: 0.44, l: 0.4902…, opacity: 1}
```
Now rotate the hue by 90°, bump up the saturation, and format as a string for CSS:
```js
c.h += 90;
c.s += 0.2;
c + ""; // rgb(198, 45, 205)
```
To fade the color slightly:
```js
c.opacity = 0.8;
c + ""; // rgba(198, 45, 205, 0.8)
```
In addition to the ubiquitous and machine-friendly [RGB](#rgb) and [HSL](#hsl) color space, d3-color supports color spaces that are designed for humans:
* [CIELAB](#lab) (*a.k.a.* “Lab”)
* [CIELCh<sub>ab</sub>](#lch) (*a.k.a.* “LCh” or “HCL”)
* Dave Greens [Cubehelix](#cubehelix)
Cubehelix features monotonic lightness, while CIELAB and its polar form CIELCh<sub>ab</sub> are perceptually uniform.
## Extensions
For additional color spaces, see:
* [d3-cam16](https://github.com/d3/d3-cam16)
* [d3-cam02](https://github.com/connorgr/d3-cam02)
* [d3-hsv](https://github.com/d3/d3-hsv)
* [d3-hcg](https://github.com/d3/d3-hcg)
* [d3-hsluv](https://github.com/petulla/d3-hsluv)
To measure color differences, see:
* [d3-color-difference](https://github.com/Evercoder/d3-color-difference)
## Installing
If you use npm, `npm install d3-color`. You can also download the [latest release on GitHub](https://github.com/d3/d3-color/releases/latest). For vanilla HTML in modern browsers, import d3-color from Skypack:
```html
<script type="module">
import {rgb} from "https://cdn.skypack.dev/d3-color@3";
const steelblue = d3.rgb("steelblue");
</script>
```
For legacy environments, you can load d3-colors UMD bundle from an npm-based CDN such as jsDelivr; a `d3` global is exported:
```html
<script src="https://cdn.jsdelivr.net/npm/d3-color@3"></script>
<script>
const steelblue = d3.rgb("steelblue");
</script>
```
[Try d3-color in your browser.](https://observablehq.com/collection/@d3/d3-color)
## API Reference
<a name="color" href="#color">#</a> d3.<b>color</b>(<i>specifier</i>) [<>](https://github.com/d3/d3-color/blob/master/src/color.js "Source")
Parses the specified [CSS Color Module Level 3](http://www.w3.org/TR/css3-color/#colorunits) *specifier* string, returning an [RGB](#rgb) or [HSL](#hsl) color, along with [CSS Color Module Level 4 hex](https://www.w3.org/TR/css-color-4/#hex-notation) *specifier* strings. If the specifier was not valid, null is returned. Some examples:
* `rgb(255, 255, 255)`
* `rgb(10%, 20%, 30%)`
* `rgba(255, 255, 255, 0.4)`
* `rgba(10%, 20%, 30%, 0.4)`
* `hsl(120, 50%, 20%)`
* `hsla(120, 50%, 20%, 0.4)`
* `#ffeeaa`
* `#fea`
* `#ffeeaa22`
* `#fea2`
* `steelblue`
The list of supported [named colors](http://www.w3.org/TR/SVG/types.html#ColorKeywords) is specified by CSS.
Note: this function may also be used with `instanceof` to test if an object is a color instance. The same is true of color subclasses, allowing you to test whether a color is in a particular color space.
<a name="color_opacity" href="#color_opacity">#</a> *color*.<b>opacity</b>
This colors opacity, typically in the range [0, 1].
<a name="color_rgb" href="#color_rgb">#</a> *color*.<b>rgb</b>() [<>](https://github.com/d3/d3-color/blob/master/src/color.js "Source")
Returns the [RGB equivalent](#rgb) of this color. For RGB colors, thats `this`.
<a name="color_copy" href="#color_copy">#</a> <i>color</i>.<b>copy</b>([<i>values</i>]) [<>](https://github.com/d3/d3-color/blob/master/src/color.js "Source")
Returns a copy of this color. If *values* is specified, any enumerable own properties of *values* are assigned to the new returned color. For example, to derive a copy of a *color* with opacity 0.5, say
```js
color.copy({opacity: 0.5})
```
<a name="color_brighter" href="#color_brighter">#</a> *color*.<b>brighter</b>([<i>k</i>]) [<>](https://github.com/d3/d3-color/blob/master/src/color.js "Source")
Returns a brighter copy of this color. If *k* is specified, it controls how much brighter the returned color should be. If *k* is not specified, it defaults to 1. The behavior of this method is dependent on the implementing color space.
<a name="color_darker" href="#color_darker">#</a> *color*.<b>darker</b>([<i>k</i>]) [<>](https://github.com/d3/d3-color/blob/master/src/color.js "Source")
Returns a darker copy of this color. If *k* is specified, it controls how much darker the returned color should be. If *k* is not specified, it defaults to 1. The behavior of this method is dependent on the implementing color space.
<a name="color_displayable" href="#color_displayable">#</a> *color*.<b>displayable</b>() [<>](https://github.com/d3/d3-color/blob/master/src/color.js "Source")
Returns true if and only if the color is displayable on standard hardware. For example, this returns false for an RGB color if any channel value is less than zero or greater than 255 when rounded, or if the opacity is not in the range [0, 1].
<a name="color_formatHex" href="#color_formatHex">#</a> *color*.<b>formatHex</b>() [<>](https://github.com/d3/d3-color/blob/master/src/color.js "Source")
Returns a hexadecimal string representing this color in RGB space, such as `#f7eaba`. If this color is not displayable, a suitable displayable color is returned instead. For example, RGB channel values greater than 255 are clamped to 255.
<a name="color_formatHsl" href="#color_formatHsl">#</a> *color*.<b>formatHsl</b>() [<>](https://github.com/d3/d3-color/blob/master/src/color.js "Source")
Returns a string representing this color according to the [CSS Color Module Level 3 specification](https://www.w3.org/TR/css-color-3/#hsl-color), such as `hsl(257, 50%, 80%)` or `hsla(257, 50%, 80%, 0.2)`. If this color is not displayable, a suitable displayable color is returned instead by clamping S and L channel values to the interval [0, 100].
<a name="color_formatRgb" href="#color_formatRgb">#</a> *color*.<b>formatRgb</b>() [<>](https://github.com/d3/d3-color/blob/master/src/color.js "Source")
Returns a string representing this color according to the [CSS Object Model specification](https://drafts.csswg.org/cssom/#serialize-a-css-component-value), such as `rgb(247, 234, 186)` or `rgba(247, 234, 186, 0.2)`. If this color is not displayable, a suitable displayable color is returned instead by clamping RGB channel values to the interval [0, 255].
<a name="color_toString" href="#color_toString">#</a> *color*.<b>toString</b>() [<>](https://github.com/d3/d3-color/blob/master/src/color.js "Source")
An alias for [*color*.formatRgb](#color_formatRgb).
<a name="rgb" href="#rgb">#</a> d3.<b>rgb</b>(<i>r</i>, <i>g</i>, <i>b</i>[, <i>opacity</i>]) [<>](https://github.com/d3/d3-color/blob/master/src/color.js "Source")<br>
<a href="#rgb">#</a> d3.<b>rgb</b>(<i>specifier</i>)<br>
<a href="#rgb">#</a> d3.<b>rgb</b>(<i>color</i>)<br>
Constructs a new [RGB](https://en.wikipedia.org/wiki/RGB_color_model) color. The channel values are exposed as `r`, `g` and `b` properties on the returned instance. Use the [RGB color picker](http://bl.ocks.org/mbostock/78d64ca7ef013b4dcf8f) to explore this color space.
If *r*, *g* and *b* are specified, these represent the channel values of the returned color; an *opacity* may also be specified. If a CSS Color Module Level 3 *specifier* string is specified, it is parsed and then converted to the RGB color space. See [color](#color) for examples. If a [*color*](#color) instance is specified, it is converted to the RGB color space using [*color*.rgb](#color_rgb). Note that unlike [*color*.rgb](#color_rgb) this method *always* returns a new instance, even if *color* is already an RGB color.
<a name="rgb_clamp" href="#rgb_clamp">#</a> *rgb*.<b>clamp</b>() [<>](https://github.com/d3/d3-color/blob/master/src/color.js "Source")
Returns a new RGB color where the `r`, `g`, and `b` channels are clamped to the range [0, 255] and rounded to the nearest integer value, and the `opacity` is clamped to the range [0, 1].
<a name="hsl" href="#hsl">#</a> d3.<b>hsl</b>(<i>h</i>, <i>s</i>, <i>l</i>[, <i>opacity</i>]) [<>](https://github.com/d3/d3-color/blob/master/src/color.js "Source")<br>
<a href="#hsl">#</a> d3.<b>hsl</b>(<i>specifier</i>)<br>
<a href="#hsl">#</a> d3.<b>hsl</b>(<i>color</i>)<br>
Constructs a new [HSL](https://en.wikipedia.org/wiki/HSL_and_HSV) color. The channel values are exposed as `h`, `s` and `l` properties on the returned instance. Use the [HSL color picker](http://bl.ocks.org/mbostock/debaad4fcce9bcee14cf) to explore this color space.
If *h*, *s* and *l* are specified, these represent the channel values of the returned color; an *opacity* may also be specified. If a CSS Color Module Level 3 *specifier* string is specified, it is parsed and then converted to the HSL color space. See [color](#color) for examples. If a [*color*](#color) instance is specified, it is converted to the RGB color space using [*color*.rgb](#color_rgb) and then converted to HSL. (Colors already in the HSL color space skip the conversion to RGB.)
<a name="hsl_clamp" href="#hsl_clamp">#</a> *hsl*.<b>clamp</b>() [<>](https://github.com/d3/d3-color/blob/master/src/color.js "Source")
Returns a new HSL color where the `h` channel is clamped to the range [0, 360), and the `s`, `l`, and `opacity` channels are clamped to the range [0, 1].
<a name="lab" href="#lab">#</a> d3.<b>lab</b>(<i>l</i>, <i>a</i>, <i>b</i>[, <i>opacity</i>]) [<>](https://github.com/d3/d3-color/blob/master/src/lab.js "Source")<br>
<a href="#lab">#</a> d3.<b>lab</b>(<i>specifier</i>)<br>
<a href="#lab">#</a> d3.<b>lab</b>(<i>color</i>)<br>
Constructs a new [CIELAB](https://en.wikipedia.org/wiki/Lab_color_space#CIELAB) color. The channel values are exposed as `l`, `a` and `b` properties on the returned instance. Use the [CIELAB color picker](http://bl.ocks.org/mbostock/9f37cc207c0cb166921b) to explore this color space. The value of *l* is typically in the range [0, 100], while *a* and *b* are typically in [-160, +160].
If *l*, *a* and *b* are specified, these represent the channel values of the returned color; an *opacity* may also be specified. If a CSS Color Module Level 3 *specifier* string is specified, it is parsed and then converted to the CIELAB color space. See [color](#color) for examples. If a [*color*](#color) instance is specified, it is converted to the RGB color space using [*color*.rgb](#color_rgb) and then converted to CIELAB. (Colors already in the CIELAB color space skip the conversion to RGB, and colors in the HCL color space are converted directly to CIELAB.)
<a name="gray" href="#gray">#</a> d3.<b>gray</b>(<i>l</i>[, <i>opacity</i>]) [<>](https://github.com/d3/d3-color/blob/master/src/lab.js "Source")<br>
Constructs a new [CIELAB](#lab) color with the specified *l* value and *a* = *b* = 0.
<a name="hcl" href="#hcl">#</a> d3.<b>hcl</b>(<i>h</i>, <i>c</i>, <i>l</i>[, <i>opacity</i>]) [<>](https://github.com/d3/d3-color/blob/master/src/lab.js "Source")<br>
<a href="#hcl">#</a> d3.<b>hcl</b>(<i>specifier</i>)<br>
<a href="#hcl">#</a> d3.<b>hcl</b>(<i>color</i>)<br>
Equivalent to [d3.lch](#lch), but with reversed argument order.
<a name="lch" href="#lch">#</a> d3.<b>lch</b>(<i>l</i>, <i>c</i>, <i>h</i>[, <i>opacity</i>]) [<>](https://github.com/d3/d3-color/blob/master/src/lab.js "Source")<br>
<a href="#lch">#</a> d3.<b>lch</b>(<i>specifier</i>)<br>
<a href="#lch">#</a> d3.<b>lch</b>(<i>color</i>)<br>
Constructs a new [CIELCh<sub>ab</sub>](https://en.wikipedia.org/wiki/CIELAB_color_space#Cylindrical_representation:_CIELCh_or_CIEHLC) color. The channel values are exposed as `l`, `c` and `h` properties on the returned instance. Use the [CIELCh<sub>ab</sub> color picker](http://bl.ocks.org/mbostock/3e115519a1b495e0bd95) to explore this color space. The value of *l* is typically in the range [0, 100], *c* is typically in [0, 230], and *h* is typically in [0, 360).
If *l*, *c*, and *h* are specified, these represent the channel values of the returned color; an *opacity* may also be specified. If a CSS Color Module Level 3 *specifier* string is specified, it is parsed and then converted to CIELCh<sub>ab</sub> color space. See [color](#color) for examples. If a [*color*](#color) instance is specified, it is converted to the RGB color space using [*color*.rgb](#color_rgb) and then converted to CIELCh<sub>ab</sub>. (Colors already in CIELCh<sub>ab</sub> color space skip the conversion to RGB, and colors in CIELAB color space are converted directly to CIELCh<sub>ab</sub>.)
<a name="cubehelix" href="#cubehelix">#</a> d3.<b>cubehelix</b>(<i>h</i>, <i>s</i>, <i>l</i>[, <i>opacity</i>]) [<>](https://github.com/d3/d3-color/blob/master/src/cubehelix.js "Source")<br>
<a href="#cubehelix">#</a> d3.<b>cubehelix</b>(<i>specifier</i>)<br>
<a href="#cubehelix">#</a> d3.<b>cubehelix</b>(<i>color</i>)<br>
Constructs a new [Cubehelix](http://www.mrao.cam.ac.uk/~dag/CUBEHELIX/) color. The channel values are exposed as `h`, `s` and `l` properties on the returned instance. Use the [Cubehelix color picker](http://bl.ocks.org/mbostock/ba8d75e45794c27168b5) to explore this color space.
If *h*, *s* and *l* are specified, these represent the channel values of the returned color; an *opacity* may also be specified. If a CSS Color Module Level 3 *specifier* string is specified, it is parsed and then converted to the Cubehelix color space. See [color](#color) for examples. If a [*color*](#color) instance is specified, it is converted to the RGB color space using [*color*.rgb](#color_rgb) and then converted to Cubehelix. (Colors already in the Cubehelix color space skip the conversion to RGB.)

54
frontend/node_modules/d3-color/package 2.json generated vendored Normal file
View File

@@ -0,0 +1,54 @@
{
"name": "d3-color",
"version": "3.1.0",
"description": "Color spaces! RGB, HSL, Cubehelix, Lab and HCL (Lch).",
"homepage": "https://d3js.org/d3-color/",
"repository": {
"type": "git",
"url": "https://github.com/d3/d3-color.git"
},
"keywords": [
"d3",
"d3-module",
"color",
"rgb",
"hsl",
"lab",
"hcl",
"lch",
"cubehelix"
],
"license": "ISC",
"author": {
"name": "Mike Bostock",
"url": "http://bost.ocks.org/mike"
},
"type": "module",
"files": [
"dist/**/*.js",
"src/**/*.js"
],
"module": "src/index.js",
"main": "src/index.js",
"jsdelivr": "dist/d3-color.min.js",
"unpkg": "dist/d3-color.min.js",
"exports": {
"umd": "./dist/d3-color.min.js",
"default": "./src/index.js"
},
"sideEffects": false,
"devDependencies": {
"eslint": "8",
"mocha": "9",
"rollup": "2",
"rollup-plugin-terser": "7"
},
"scripts": {
"test": "mocha 'test/**/*-test.js' && eslint src test",
"prepublishOnly": "rm -rf dist && yarn test && rollup -c",
"postpublish": "git push && git push --tags && cd ../d3.github.com && git pull && cp ../${npm_package_name}/dist/${npm_package_name}.js ${npm_package_name}.v${npm_package_version%%.*}.js && cp ../${npm_package_name}/dist/${npm_package_name}.min.js ${npm_package_name}.v${npm_package_version%%.*}.min.js && git add ${npm_package_name}.v${npm_package_version%%.*}.js ${npm_package_name}.v${npm_package_version%%.*}.min.js && git commit -m \"${npm_package_name} ${npm_package_version}\" && git push && cd -"
},
"engines": {
"node": ">=12"
}
}

28
frontend/node_modules/d3-ease/LICENSE 2 generated vendored Normal file
View File

@@ -0,0 +1,28 @@
Copyright 2010-2021 Mike Bostock
Copyright 2001 Robert Penner
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice, this
list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
* Neither the name of the author nor the names of contributors may be used to
endorse or promote products derived from this software without specific prior
written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

253
frontend/node_modules/d3-ease/README 2.md generated vendored Normal file
View File

@@ -0,0 +1,253 @@
# d3-ease
*Easing* is a method of distorting time to control apparent motion in animation. It is most commonly used for [slow-in, slow-out](https://en.wikipedia.org/wiki/12_basic_principles_of_animation#Slow_In_and_Slow_Out). By easing time, [animated transitions](https://github.com/d3/d3-transition) are smoother and exhibit more plausible motion.
The easing types in this module implement the [ease method](#ease_ease), which takes a normalized time *t* and returns the corresponding “eased” time *tʹ*. Both the normalized time and the eased time are typically in the range [0,1], where 0 represents the start of the animation and 1 represents the end; some easing types, such as [elastic](#easeElastic), may return eased times slightly outside this range. A good easing type should return 0 if *t* = 0 and 1 if *t* = 1. See the [easing explorer](https://observablehq.com/@d3/easing) for a visual demonstration.
These easing types are largely based on work by [Robert Penner](http://robertpenner.com/easing/).
## Installing
If you use npm, `npm install d3-ease`. You can also download the [latest release on GitHub](https://github.com/d3/d3-ease/releases/latest). For vanilla HTML in modern browsers, import d3-ease from Skypack:
```html
<script type="module">
import {easeCubic} from "https://cdn.skypack.dev/d3-ease@3";
const e = easeCubic(0.25);
</script>
```
For legacy environments, you can load d3-eases UMD bundle from an npm-based CDN such as jsDelivr; a `d3` global is exported:
```html
<script src="https://cdn.jsdelivr.net/npm/d3-ease@3"></script>
<script>
const e = d3.easeCubic(0.25);
</script>
```
[Try d3-ease in your browser.](https://observablehq.com/@d3/easing-animations)
## API Reference
<a name="_ease" href="#_ease">#</a> <i>ease</i>(<i>t</i>)
Given the specified normalized time *t*, typically in the range [0,1], returns the “eased” time *tʹ*, also typically in [0,1]. 0 represents the start of the animation and 1 represents the end. A good implementation returns 0 if *t* = 0 and 1 if *t* = 1. See the [easing explorer](https://observablehq.com/@d3/easing) for a visual demonstration. For example, to apply [cubic](#easeCubic) easing:
```js
const te = d3.easeCubic(t);
```
Similarly, to apply custom [elastic](#easeElastic) easing:
```js
// Before the animation starts, create your easing function.
const customElastic = d3.easeElastic.period(0.4);
// During the animation, apply the easing function.
const te = customElastic(t);
```
<a name="easeLinear" href="#easeLinear">#</a> d3.<b>easeLinear</b>(<i>t</i>) [<>](https://github.com/d3/d3-ease/blob/master/src/linear.js "Source")
Linear easing; the identity function; *linear*(*t*) returns *t*.
[<img src="https://raw.githubusercontent.com/d3/d3-ease/master/img/linear.png" alt="linear">](https://observablehq.com/@d3/easing#linear)
<a name="easePolyIn" href="#easePolyIn">#</a> d3.<b>easePolyIn</b>(<i>t</i>) [<>](https://github.com/d3/d3-ease/blob/master/src/poly.js#L3 "Source")
Polynomial easing; raises *t* to the specified [exponent](#poly_exponent). If the exponent is not specified, it defaults to 3, equivalent to [cubicIn](#easeCubicIn).
[<img src="https://raw.githubusercontent.com/d3/d3-ease/master/img/polyIn.png" alt="polyIn">](https://observablehq.com/@d3/easing#polyIn)
<a name="easePolyOut" href="#easePolyOut">#</a> d3.<b>easePolyOut</b>(<i>t</i>) [<>](https://github.com/d3/d3-ease/blob/master/src/poly.js#L15 "Source")
Reverse polynomial easing; equivalent to 1 - [polyIn](#easePolyIn)(1 - *t*). If the [exponent](#poly_exponent) is not specified, it defaults to 3, equivalent to [cubicOut](#easeCubicOut).
[<img src="https://raw.githubusercontent.com/d3/d3-ease/master/img/polyOut.png" alt="polyOut">](https://observablehq.com/@d3/easing#polyOut)
<a name="easePoly" href="#easePoly">#</a> d3.<b>easePoly</b>(<i>t</i>) [<>](https://github.com/d3/d3-ease/blob/master/src/poly.js "Source")
<br><a name="easePolyInOut" href="#easePolyInOut">#</a> d3.<b>easePolyInOut</b>(<i>t</i>) [<>](https://github.com/d3/d3-ease/blob/master/src/poly.js#L27 "Source")
Symmetric polynomial easing; scales [polyIn](#easePolyIn) for *t* in [0, 0.5] and [polyOut](#easePolyOut) for *t* in [0.5, 1]. If the [exponent](#poly_exponent) is not specified, it defaults to 3, equivalent to [cubic](#easeCubic).
[<img src="https://raw.githubusercontent.com/d3/d3-ease/master/img/polyInOut.png" alt="polyInOut">](https://observablehq.com/@d3/easing#polyInOut)
<a name="poly_exponent" href="#poly_exponent">#</a> <i>poly</i>.<b>exponent</b>(<i>e</i>) [<>](https://github.com/d3/d3-ease/blob/master/src/poly.js#L1 "Source")
Returns a new polynomial easing with the specified exponent *e*. For example, to create equivalents of [linear](#easeLinear), [quad](#easeQuad), and [cubic](#easeCubic):
```js
const linear = d3.easePoly.exponent(1);
const quad = d3.easePoly.exponent(2);
const cubic = d3.easePoly.exponent(3);
```
<a name="easeQuadIn" href="#easeQuadIn">#</a> d3.<b>easeQuadIn</b>(<i>t</i>) [<>](https://github.com/d3/d3-ease/blob/master/src/quad.js#L1 "Source")
Quadratic easing; equivalent to [polyIn](#easePolyIn).[exponent](#poly_exponent)(2).
[<img src="https://raw.githubusercontent.com/d3/d3-ease/master/img/quadIn.png" alt="quadIn">](https://observablehq.com/@d3/easing#quadIn)
<a name="easeQuadOut" href="#easeQuadOut">#</a> d3.<b>easeQuadOut</b>(<i>t</i>) [<>](https://github.com/d3/d3-ease/blob/master/src/quad.js#L5 "Source")
Reverse quadratic easing; equivalent to 1 - [quadIn](#easeQuadIn)(1 - *t*). Also equivalent to [polyOut](#easePolyOut).[exponent](#poly_exponent)(2).
[<img src="https://raw.githubusercontent.com/d3/d3-ease/master/img/quadOut.png" alt="quadOut">](https://observablehq.com/@d3/easing#quadOut)
<a name="easeQuad" href="#easeQuad">#</a> d3.<b>easeQuad</b>(<i>t</i>) [<>](https://github.com/d3/d3-ease/blob/master/src/quad.js "Source")
<br><a name="easeQuadInOut" href="#easeQuadInOut">#</a> d3.<b>easeQuadInOut</b>(<i>t</i>) [<>](https://github.com/d3/d3-ease/blob/master/src/quad.js#L9 "Source")
Symmetric quadratic easing; scales [quadIn](#easeQuadIn) for *t* in [0, 0.5] and [quadOut](#easeQuadOut) for *t* in [0.5, 1]. Also equivalent to [poly](#easePoly).[exponent](#poly_exponent)(2).
[<img src="https://raw.githubusercontent.com/d3/d3-ease/master/img/quadInOut.png" alt="quadInOut">](https://observablehq.com/@d3/easing#quadInOut)
<a name="easeCubicIn" href="#easeCubicIn">#</a> d3.<b>easeCubicIn</b>(<i>t</i>) [<>](https://github.com/d3/d3-ease/blob/master/src/cubic.js#L1 "Source")
Cubic easing; equivalent to [polyIn](#easePolyIn).[exponent](#poly_exponent)(3).
[<img src="https://raw.githubusercontent.com/d3/d3-ease/master/img/cubicIn.png" alt="cubicIn">](https://observablehq.com/@d3/easing#cubicIn)
<a name="easeCubicOut" href="#easeCubicOut">#</a> d3.<b>easeCubicOut</b>(<i>t</i>) [<>](https://github.com/d3/d3-ease/blob/master/src/cubic.js#L5 "Source")
Reverse cubic easing; equivalent to 1 - [cubicIn](#easeCubicIn)(1 - *t*). Also equivalent to [polyOut](#easePolyOut).[exponent](#poly_exponent)(3).
[<img src="https://raw.githubusercontent.com/d3/d3-ease/master/img/cubicOut.png" alt="cubicOut">](https://observablehq.com/@d3/easing#cubicOut)
<a name="easeCubic" href="#easeCubic">#</a> d3.<b>easeCubic</b>(<i>t</i>) [<>](https://github.com/d3/d3-ease/blob/master/src/cubic.js "Source")
<br><a name="easeCubicInOut" href="#easeCubicInOut">#</a> d3.<b>easeCubicInOut</b>(<i>t</i>) [<>](https://github.com/d3/d3-ease/blob/master/src/cubic.js#L9 "Source")
Symmetric cubic easing; scales [cubicIn](#easeCubicIn) for *t* in [0, 0.5] and [cubicOut](#easeCubicOut) for *t* in [0.5, 1]. Also equivalent to [poly](#easePoly).[exponent](#poly_exponent)(3).
[<img src="https://raw.githubusercontent.com/d3/d3-ease/master/img/cubicInOut.png" alt="cubicInOut">](https://observablehq.com/@d3/easing#cubicInOut)
<a name="easeSinIn" href="#easeSinIn">#</a> d3.<b>easeSinIn</b>(<i>t</i>) [<>](https://github.com/d3/d3-ease/blob/master/src/sin.js#L4 "Source")
Sinusoidal easing; returns sin(*t*).
[<img src="https://raw.githubusercontent.com/d3/d3-ease/master/img/sinIn.png" alt="sinIn">](https://observablehq.com/@d3/easing#sinIn)
<a name="easeSinOut" href="#easeSinOut">#</a> d3.<b>easeSinOut</b>(<i>t</i>) [<>](https://github.com/d3/d3-ease/blob/master/src/sin.js#L8 "Source")
Reverse sinusoidal easing; equivalent to 1 - [sinIn](#easeSinIn)(1 - *t*).
[<img src="https://raw.githubusercontent.com/d3/d3-ease/master/img/sinOut.png" alt="sinOut">](https://observablehq.com/@d3/easing#sinOut)
<a name="easeSin" href="#easeSin">#</a> d3.<b>easeSin</b>(<i>t</i>) [<>](https://github.com/d3/d3-ease/blob/master/src/sin.js "Source")
<br><a name="easeSinInOut" href="#easeSinInOut">#</a> d3.<b>easeSinInOut</b>(<i>t</i>) [<>](https://github.com/d3/d3-ease/blob/master/src/sin.js#L12 "Source")
Symmetric sinusoidal easing; scales [sinIn](#easeSinIn) for *t* in [0, 0.5] and [sinOut](#easeSinOut) for *t* in [0.5, 1].
[<img src="https://raw.githubusercontent.com/d3/d3-ease/master/img/sinInOut.png" alt="sinInOut">](https://observablehq.com/@d3/easing#sinInOut)
<a name="easeExpIn" href="#easeExpIn">#</a> d3.<b>easeExpIn</b>(<i>t</i>) [<>](https://github.com/d3/d3-ease/blob/master/src/exp.js#L1 "Source")
Exponential easing; raises 2 to the exponent 10 \* (*t* - 1).
[<img src="https://raw.githubusercontent.com/d3/d3-ease/master/img/expIn.png" alt="expIn">](https://observablehq.com/@d3/easing#expIn)
<a name="easeExpOut" href="#easeExpOut">#</a> d3.<b>easeExpOut</b>(<i>t</i>) [<>](https://github.com/d3/d3-ease/blob/master/src/exp.js#L5 "Source")
Reverse exponential easing; equivalent to 1 - [expIn](#easeExpIn)(1 - *t*).
[<img src="https://raw.githubusercontent.com/d3/d3-ease/master/img/expOut.png" alt="expOut">](https://observablehq.com/@d3/easing#expOut)
<a name="easeExp" href="#easeExp">#</a> d3.<b>easeExp</b>(<i>t</i>) [<>](https://github.com/d3/d3-ease/blob/master/src/exp.js "Source")
<br><a name="easeExpInOut" href="#easeExpInOut">#</a> d3.<b>easeExpInOut</b>(<i>t</i>) [<>](https://github.com/d3/d3-ease/blob/master/src/exp.js#L9 "Source")
Symmetric exponential easing; scales [expIn](#easeExpIn) for *t* in [0, 0.5] and [expOut](#easeExpOut) for *t* in [0.5, 1].
[<img src="https://raw.githubusercontent.com/d3/d3-ease/master/img/expInOut.png" alt="expInOut">](https://observablehq.com/@d3/easing#expInOut)
<a name="easeCircleIn" href="#easeCircleIn">#</a> d3.<b>easeCircleIn</b>(<i>t</i>) [<>](https://github.com/d3/d3-ease/blob/master/src/circle.js#L1 "Source")
Circular easing.
[<img src="https://raw.githubusercontent.com/d3/d3-ease/master/img/circleIn.png" alt="circleIn">](https://observablehq.com/@d3/easing#circleIn)
<a name="easeCircleOut" href="#easeCircleOut">#</a> d3.<b>easeCircleOut</b>(<i>t</i>) [<>](https://github.com/d3/d3-ease/blob/master/src/circle.js#L5 "Source")
Reverse circular easing; equivalent to 1 - [circleIn](#easeCircleIn)(1 - *t*).
[<img src="https://raw.githubusercontent.com/d3/d3-ease/master/img/circleOut.png" alt="circleOut">](https://observablehq.com/@d3/easing#circleOut)
<a name="easeCircle" href="#easeCircle">#</a> d3.<b>easeCircle</b>(<i>t</i>) [<>](https://github.com/d3/d3-ease/blob/master/src/circle.js "Source")
<br><a name="easeCircleInOut" href="#easeCircleInOut">#</a> d3.<b>easeCircleInOut</b>(<i>t</i>) [<>](https://github.com/d3/d3-ease/blob/master/src/circle.js#L9 "Source")
Symmetric circular easing; scales [circleIn](#easeCircleIn) for *t* in [0, 0.5] and [circleOut](#easeCircleOut) for *t* in [0.5, 1].
[<img src="https://raw.githubusercontent.com/d3/d3-ease/master/img/circleInOut.png" alt="circleInOut">](https://observablehq.com/@d3/easing#circleInOut)
<a name="easeElasticIn" href="#easeElasticIn">#</a> d3.<b>easeElasticIn</b>(<i>t</i>) [<>](https://github.com/d3/d3-ease/blob/master/src/elastic.js#L5 "Source")
Elastic easing, like a rubber band. The [amplitude](#elastic_amplitude) and [period](#elastic_period) of the oscillation are configurable; if not specified, they default to 1 and 0.3, respectively.
[<img src="https://raw.githubusercontent.com/d3/d3-ease/master/img/elasticIn.png" alt="elasticIn">](https://observablehq.com/@d3/easing#elasticIn)
<a name="easeElastic" href="#easeElastic">#</a> d3.<b>easeElastic</b>(<i>t</i>) [<>](https://github.com/d3/d3-ease/blob/master/src/elastic.js "Source")
<br><a name="easeElasticOut" href="#easeElasticOut">#</a> d3.<b>easeElasticOut</b>(<i>t</i>) [<>](https://github.com/d3/d3-ease/blob/master/src/elastic.js#L18 "Source")
Reverse elastic easing; equivalent to 1 - [elasticIn](#easeElasticIn)(1 - *t*).
[<img src="https://raw.githubusercontent.com/d3/d3-ease/master/img/elasticOut.png" alt="elasticOut">](https://observablehq.com/@d3/easing#elasticOut)
<a name="easeElasticInOut" href="#easeElasticInOut">#</a> d3.<b>easeElasticInOut</b>(<i>t</i>) [<>](https://github.com/d3/d3-ease/blob/master/src/elastic.js#L31 "Source")
Symmetric elastic easing; scales [elasticIn](#easeElasticIn) for *t* in [0, 0.5] and [elasticOut](#easeElasticOut) for *t* in [0.5, 1].
[<img src="https://raw.githubusercontent.com/d3/d3-ease/master/img/elasticInOut.png" alt="elasticInOut">](https://observablehq.com/@d3/easing#elasticInOut)
<a name="elastic_amplitude" href="#elastic_amplitude">#</a> <i>elastic</i>.<b>amplitude</b>(<i>a</i>) [<>](https://github.com/d3/d3-ease/blob/master/src/elastic.js#L40 "Source")
Returns a new elastic easing with the specified amplitude *a*.
<a name="elastic_period" href="#elastic_period">#</a> <i>elastic</i>.<b>period</b>(<i>p</i>) [<>](https://github.com/d3/d3-ease/blob/master/src/elastic.js#L41 "Source")
Returns a new elastic easing with the specified period *p*.
<a name="easeBackIn" href="#easeBackIn">#</a> d3.<b>easeBackIn</b>(<i>t</i>) [<>](https://github.com/d3/d3-ease/blob/master/src/back.js#L3 "Source")
[Anticipatory](https://en.wikipedia.org/wiki/12_basic_principles_of_animation#Anticipation) easing, like a dancer bending his knees before jumping off the floor. The degree of [overshoot](#back_overshoot) is configurable; if not specified, it defaults to 1.70158.
[<img src="https://raw.githubusercontent.com/d3/d3-ease/master/img/backIn.png" alt="backIn">](https://observablehq.com/@d3/easing#backIn)
<a name="easeBackOut" href="#easeBackOut">#</a> d3.<b>easeBackOut</b>(<i>t</i>) [<>](https://github.com/d3/d3-ease/blob/master/src/back.js#L15 "Source")
Reverse anticipatory easing; equivalent to 1 - [backIn](#easeBackIn)(1 - *t*).
[<img src="https://raw.githubusercontent.com/d3/d3-ease/master/img/backOut.png" alt="backOut">](https://observablehq.com/@d3/easing#backOut)
<a name="easeBack" href="#easeBack">#</a> d3.<b>easeBack</b>(<i>t</i>) [<>](https://github.com/d3/d3-ease/blob/master/src/back.js "Source")
<br><a name="easeBackInOut" href="#easeBackInOut">#</a> d3.<b>easeBackInOut</b>(<i>t</i>) [<>](https://github.com/d3/d3-ease/blob/master/src/back.js#L27 "Source")
Symmetric anticipatory easing; scales [backIn](#easeBackIn) for *t* in [0, 0.5] and [backOut](#easeBackOut) for *t* in [0.5, 1].
[<img src="https://raw.githubusercontent.com/d3/d3-ease/master/img/backInOut.png" alt="backInOut">](https://observablehq.com/@d3/easing#backInOut)
<a name="back_overshoot" href="#back_overshoot">#</a> <i>back</i>.<b>overshoot</b>(<i>s</i>) [<>](https://github.com/d3/d3-ease/blob/master/src/back.js#L1 "Source")
Returns a new back easing with the specified overshoot *s*.
<a name="easeBounceIn" href="#easeBounceIn">#</a> d3.<b>easeBounceIn</b>(<i>t</i>) [<>](https://github.com/d3/d3-ease/blob/master/src/bounce.js#L12 "Source")
Bounce easing, like a rubber ball.
[<img src="https://raw.githubusercontent.com/d3/d3-ease/master/img/bounceIn.png" alt="bounceIn">](https://observablehq.com/@d3/easing#bounceIn)
<a name="easeBounce" href="#easeBounce">#</a> d3.<b>easeBounce</b>(<i>t</i>) [<>](https://github.com/d3/d3-ease/blob/master/src/bounce.js "Source")
<br><a name="easeBounceOut" href="#easeBounceOut">#</a> d3.<b>easeBounceOut</b>(<i>t</i>) [<>](https://github.com/d3/d3-ease/blob/master/src/bounce.js#L16 "Source")
Reverse bounce easing; equivalent to 1 - [bounceIn](#easeBounceIn)(1 - *t*).
[<img src="https://raw.githubusercontent.com/d3/d3-ease/master/img/bounceOut.png" alt="bounceOut">](https://observablehq.com/@d3/easing#bounceOut)
<a name="easeBounceInOut" href="#easeBounceInOut">#</a> d3.<b>easeBounceInOut</b>(<i>t</i>) [<>](https://github.com/d3/d3-ease/blob/master/src/bounce.js#L20 "Source")
Symmetric bounce easing; scales [bounceIn](#easeBounceIn) for *t* in [0, 0.5] and [bounceOut](#easeBounceOut) for *t* in [0.5, 1].
[<img src="https://raw.githubusercontent.com/d3/d3-ease/master/img/bounceInOut.png" alt="bounceInOut">](https://observablehq.com/@d3/easing#bounceInOut)

51
frontend/node_modules/d3-ease/package 2.json generated vendored Normal file
View File

@@ -0,0 +1,51 @@
{
"name": "d3-ease",
"version": "3.0.1",
"description": "Easing functions for smooth animation.",
"homepage": "https://d3js.org/d3-ease/",
"repository": {
"type": "git",
"url": "https://github.com/d3/d3-ease.git"
},
"keywords": [
"d3",
"d3-module",
"ease",
"easing",
"animation",
"transition"
],
"license": "BSD-3-Clause",
"author": {
"name": "Mike Bostock",
"url": "http://bost.ocks.org/mike"
},
"type": "module",
"files": [
"dist/**/*.js",
"src/**/*.js"
],
"module": "src/index.js",
"main": "src/index.js",
"jsdelivr": "dist/d3-ease.min.js",
"unpkg": "dist/d3-ease.min.js",
"exports": {
"umd": "./dist/d3-ease.min.js",
"default": "./src/index.js"
},
"sideEffects": false,
"devDependencies": {
"eslint": "7",
"mocha": "8",
"rollup": "2",
"rollup-plugin-terser": "7"
},
"scripts": {
"test": "mocha 'test/**/*-test.js' && eslint src test",
"prepublishOnly": "rm -rf dist && yarn test && rollup -c",
"postpublish": "git push && git push --tags && cd ../d3.github.com && git pull && cp ../${npm_package_name}/dist/${npm_package_name}.js ${npm_package_name}.v${npm_package_version%%.*}.js && cp ../${npm_package_name}/dist/${npm_package_name}.min.js ${npm_package_name}.v${npm_package_version%%.*}.min.js && git add ${npm_package_name}.v${npm_package_version%%.*}.js ${npm_package_name}.v${npm_package_version%%.*}.min.js && git commit -m \"${npm_package_name} ${npm_package_version}\" && git push && cd -"
},
"engines": {
"node": ">=12"
}
}

13
frontend/node_modules/d3-interpolate/LICENSE 2 generated vendored Normal file
View File

@@ -0,0 +1,13 @@
Copyright 2010-2021 Mike Bostock
Permission to use, copy, modify, and/or distribute this software for any purpose
with or without fee is hereby granted, provided that the above copyright notice
and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
THIS SOFTWARE.

268
frontend/node_modules/d3-interpolate/README 2.md generated vendored Normal file
View File

@@ -0,0 +1,268 @@
# d3-interpolate
This module provides a variety of interpolation methods for blending between two values. Values may be numbers, colors, strings, arrays, or even deeply-nested objects. For example:
```js
const i = d3.interpolateNumber(10, 20);
i(0.0); // 10
i(0.2); // 12
i(0.5); // 15
i(1.0); // 20
```
The returned function `i` is called an *interpolator*. Given a starting value *a* and an ending value *b*, it takes a parameter *t* in the domain [0, 1] and returns the corresponding interpolated value between *a* and *b*. An interpolator typically returns a value equivalent to *a* at *t* = 0 and a value equivalent to *b* at *t* = 1.
You can interpolate more than just numbers. To find the perceptual midpoint between steelblue and brown:
```js
d3.interpolateLab("steelblue", "brown")(0.5); // "rgb(142, 92, 109)"
```
Heres a more elaborate example demonstrating type inference used by [interpolate](#interpolate):
```js
const i = d3.interpolate({colors: ["red", "blue"]}, {colors: ["white", "black"]});
i(0.0); // {colors: ["rgb(255, 0, 0)", "rgb(0, 0, 255)"]}
i(0.5); // {colors: ["rgb(255, 128, 128)", "rgb(0, 0, 128)"]}
i(1.0); // {colors: ["rgb(255, 255, 255)", "rgb(0, 0, 0)"]}
```
Note that the generic value interpolator detects not only nested objects and arrays, but also color strings and numbers embedded in strings!
## Installing
If you use npm, `npm install d3-interpolate`. You can also download the [latest release on GitHub](https://github.com/d3/d3-interpolate/releases/latest). For vanilla HTML in modern browsers, import d3-interpolate from Skypack:
```html
<script type="module">
import {interpolateRgb} from "https://cdn.skypack.dev/d3-interpolate@3";
const interpolate = interpolateRgb("steelblue", "brown");
</script>
```
For legacy environments, you can load d3-interpolates UMD bundle from an npm-based CDN such as jsDelivr; a `d3` global is exported. (If using [color interpolation](#color-spaces), also load [d3-color](https://github.com/d3/d3-color).)
```html
<script src="https://cdn.jsdelivr.net/npm/d3-color@3"></script>
<script src="https://cdn.jsdelivr.net/npm/d3-interpolate@3"></script>
<script>
const interpolate = d3.interpolateRgb("steelblue", "brown");
</script>
```
## API Reference
<a name="interpolate" href="#interpolate">#</a> d3.<b>interpolate</b>(<i>a</i>, <i>b</i>) · [Source](https://github.com/d3/d3-interpolate/blob/master/src/value.js), [Examples](https://observablehq.com/@d3/d3-interpolate)
Returns an interpolator between the two arbitrary values *a* and *b*. The interpolator implementation is based on the type of the end value *b*, using the following algorithm:
1. If *b* is null, undefined or a boolean, use the constant *b*.
2. If *b* is a number, use [interpolateNumber](#interpolateNumber).
3. If *b* is a [color](https://github.com/d3/d3-color/blob/master/README.md#color) or a string coercible to a color, use [interpolateRgb](#interpolateRgb).
4. If *b* is a [date](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date), use [interpolateDate](#interpolateDate).
5. If *b* is a string, use [interpolateString](#interpolateString).
6. If *b* is a [typed array](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/TypedArray) of numbers, use [interpolateNumberArray](#interpolateNumberArray).
7. If *b* is a generic [array](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/isArray), use [interpolateArray](#interpolateArray).
8. If *b* is coercible to a number, use [interpolateNumber](#interpolateNumber).
9. Use [interpolateObject](#interpolateObject).
Based on the chosen interpolator, *a* is coerced to the suitable corresponding type.
<a name="interpolateNumber" href="#interpolateNumber">#</a> d3.<b>interpolateNumber</b>(<i>a</i>, <i>b</i>) · [Source](https://github.com/d3/d3-interpolate/blob/master/src/number.js), [Examples](https://observablehq.com/@d3/d3-interpolatenumber)
Returns an interpolator between the two numbers *a* and *b*. The returned interpolator is equivalent to:
```js
function interpolator(t) {
return a * (1 - t) + b * t;
}
```
Caution: avoid interpolating to or from the number zero when the interpolator is used to generate a string. When very small values are stringified, they may be converted to scientific notation, which is an invalid attribute or style property value in older browsers. For example, the number `0.0000001` is converted to the string `"1e-7"`. This is particularly noticeable with interpolating opacity. To avoid scientific notation, start or end the transition at 1e-6: the smallest value that is not stringified in scientific notation.
<a name="interpolateRound" href="#interpolateRound">#</a> d3.<b>interpolateRound</b>(<i>a</i>, <i>b</i>) · [Source](https://github.com/d3/d3-interpolate/blob/master/src/round.js), [Examples](https://observablehq.com/@d3/d3-interpolatenumber)
Returns an interpolator between the two numbers *a* and *b*; the interpolator is similar to [interpolateNumber](#interpolateNumber), except it will round the resulting value to the nearest integer.
<a name="interpolateString" href="#interpolateString">#</a> d3.<b>interpolateString</b>(<i>a</i>, <i>b</i>) · [Source](https://github.com/d3/d3-interpolate/blob/master/src/string.js), [Examples](https://observablehq.com/@d3/d3-interpolatestring)
Returns an interpolator between the two strings *a* and *b*. The string interpolator finds numbers embedded in *a* and *b*, where each number is of the form understood by JavaScript. A few examples of numbers that will be detected within a string: `-1`, `42`, `3.14159`, and `6.0221413e+23`.
For each number embedded in *b*, the interpolator will attempt to find a corresponding number in *a*. If a corresponding number is found, a numeric interpolator is created using [interpolateNumber](#interpolateNumber). The remaining parts of the string *b* are used as a template: the static parts of the string *b* remain constant for the interpolation, with the interpolated numeric values embedded in the template.
For example, if *a* is `"300 12px sans-serif"`, and *b* is `"500 36px Comic-Sans"`, two embedded numbers are found. The remaining static parts (of string *b*) are a space between the two numbers (`" "`), and the suffix (`"px Comic-Sans"`). The result of the interpolator at *t* = 0.5 is `"400 24px Comic-Sans"`.
<a name="interpolateDate" href="#interpolateDate">#</a> d3.<b>interpolateDate</b>(<i>a</i>, <i>b</i>) · [Source](https://github.com/d3/d3-interpolate/blob/master/src/date.js), [Examples](https://observablehq.com/@d3/d3-interpolatedate)
Returns an interpolator between the two [dates](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date) *a* and *b*.
Note: **no defensive copy** of the returned date is created; the same Date instance is returned for every evaluation of the interpolator. No copy is made for performance reasons; interpolators are often part of the inner loop of [animated transitions](https://github.com/d3/d3-transition).
<a name="interpolateArray" href="#interpolateArray">#</a> d3.<b>interpolateArray</b>(<i>a</i>, <i>b</i>) · [Source](https://github.com/d3/d3-interpolate/blob/master/src/array.js), [Examples](https://observablehq.com/@d3/d3-interpolateobject)
Returns an interpolator between the two arrays *a* and *b*. If *b* is a typed array (e.g., Float64Array), [interpolateNumberArray](#interpolateNumberArray) is called instead.
Internally, an array template is created that is the same length as *b*. For each element in *b*, if there exists a corresponding element in *a*, a generic interpolator is created for the two elements using [interpolate](#interpolate). If there is no such element, the static value from *b* is used in the template. Then, for the given parameter *t*, the templates embedded interpolators are evaluated. The updated array template is then returned.
For example, if *a* is the array `[0, 1]` and *b* is the array `[1, 10, 100]`, then the result of the interpolator for *t* = 0.5 is the array `[0.5, 5.5, 100]`.
Note: **no defensive copy** of the template array is created; modifications of the returned array may adversely affect subsequent evaluation of the interpolator. No copy is made for performance reasons; interpolators are often part of the inner loop of [animated transitions](https://github.com/d3/d3-transition).
<a name="interpolateNumberArray" href="#interpolateNumberArray">#</a> d3.<b>interpolateNumberArray</b>(<i>a</i>, <i>b</i>) · [Source](https://github.com/d3/d3-interpolate/blob/master/src/numberArray.js), [Examples](https://observablehq.com/@d3/d3-interpolatenumberarray)
Returns an interpolator between the two arrays of numbers *a* and *b*. Internally, an array template is created that is the same type and length as *b*. For each element in *b*, if there exists a corresponding element in *a*, the values are directly interpolated in the array template. If there is no such element, the static value from *b* is copied. The updated array template is then returned.
Note: For performance reasons, **no defensive copy** is made of the template array and the arguments *a* and *b*; modifications of these arrays may affect subsequent evaluation of the interpolator.
<a name="interpolateObject" href="#interpolateObject">#</a> d3.<b>interpolateObject</b>(<i>a</i>, <i>b</i>) · [Source](https://github.com/d3/d3-interpolate/blob/master/src/object.js), [Examples](https://observablehq.com/@d3/d3-interpolateobject)
Returns an interpolator between the two objects *a* and *b*. Internally, an object template is created that has the same properties as *b*. For each property in *b*, if there exists a corresponding property in *a*, a generic interpolator is created for the two elements using [interpolate](#interpolate). If there is no such property, the static value from *b* is used in the template. Then, for the given parameter *t*, the template's embedded interpolators are evaluated and the updated object template is then returned.
For example, if *a* is the object `{x: 0, y: 1}` and *b* is the object `{x: 1, y: 10, z: 100}`, the result of the interpolator for *t* = 0.5 is the object `{x: 0.5, y: 5.5, z: 100}`.
Object interpolation is particularly useful for *dataspace interpolation*, where data is interpolated rather than attribute values. For example, you can interpolate an object which describes an arc in a pie chart, and then use [d3.arc](https://github.com/d3/d3-shape/blob/master/README.md#arc) to compute the new SVG path data.
Note: **no defensive copy** of the template object is created; modifications of the returned object may adversely affect subsequent evaluation of the interpolator. No copy is made for performance reasons; interpolators are often part of the inner loop of [animated transitions](https://github.com/d3/d3-transition).
<a name="interpolateTransformCss" href="#interpolateTransformCss">#</a> d3.<b>interpolateTransformCss</b>(<i>a</i>, <i>b</i>) · [Source](https://github.com/d3/d3-interpolate/blob/master/src/transform/index.js#L62), [Examples](https://observablehq.com/@d3/d3-interpolatetransformcss)
Returns an interpolator between the two 2D CSS transforms represented by *a* and *b*. Each transform is decomposed to a standard representation of translate, rotate, *x*-skew and scale; these component transformations are then interpolated. This behavior is standardized by CSS: see [matrix decomposition for animation](http://www.w3.org/TR/css3-2d-transforms/#matrix-decomposition).
<a name="interpolateTransformSvg" href="#interpolateTransformSvg">#</a> d3.<b>interpolateTransformSvg</b>(<i>a</i>, <i>b</i>) · [Source](https://github.com/d3/d3-interpolate/blob/master/src/transform/index.js#L63), [Examples](https://observablehq.com/@d3/d3-interpolatetransformcss)
Returns an interpolator between the two 2D SVG transforms represented by *a* and *b*. Each transform is decomposed to a standard representation of translate, rotate, *x*-skew and scale; these component transformations are then interpolated. This behavior is standardized by CSS: see [matrix decomposition for animation](http://www.w3.org/TR/css3-2d-transforms/#matrix-decomposition).
<a name="interpolateZoom" href="#interpolateZoom">#</a> d3.<b>interpolateZoom</b>(<i>a</i>, <i>b</i>) · [Source](https://github.com/d3/d3-interpolate/blob/master/src/zoom.js), [Examples](https://observablehq.com/@d3/d3-interpolatezoom)
Returns an interpolator between the two views *a* and *b* of a two-dimensional plane, based on [“Smooth and efficient zooming and panning”](http://www.win.tue.nl/~vanwijk/zoompan.pdf) by Jarke J. van Wijk and Wim A.A. Nuij. Each view is defined as an array of three numbers: *cx*, *cy* and *width*. The first two coordinates *cx*, *cy* represent the center of the viewport; the last coordinate *width* represents the size of the viewport.
The returned interpolator exposes a *duration* property which encodes the recommended transition duration in milliseconds. This duration is based on the path length of the curved trajectory through *x,y* space. If you want a slower or faster transition, multiply this by an arbitrary scale factor (<i>V</i> as described in the original paper).
<a name="interpolateZoom_rho" href="#interpolateZoom_rho">#</a> *interpolateZoom*.<b>rho</b>(<i>rho</i>) · [Source](https://github.com/d3/d3-interpolate/blob/master/src/zoom.js)<!-- , [Examples](https://observablehq.com/@d3/interpolatezoom-rho) -->
Given a [zoom interpolator](#interpolateZoom), returns a new zoom interpolator using the specified curvature *rho*. When *rho* is close to 0, the interpolator is almost linear. The default curvature is sqrt(2).
<a name="interpolateDiscrete" href="#interpolateDiscrete">#</a> d3.<b>interpolateDiscrete</b>(<i>values</i>) · [Source](https://github.com/d3/d3-interpolate/blob/master/src/discrete.js), [Examples](https://observablehq.com/@d3/d3-interpolatediscrete)
Returns a discrete interpolator for the given array of *values*. The returned interpolator maps *t* in [0, 1 / *n*) to *values*[0], *t* in [1 / *n*, 2 / *n*) to *values*[1], and so on, where *n* = *values*.length. In effect, this is a lightweight [quantize scale](https://github.com/d3/d3-scale/blob/master/README.md#quantize-scales) with a fixed domain of [0, 1].
### Sampling
<a name="quantize" href="#quantize">#</a> d3.<b>quantize</b>(<i>interpolator</i>, <i>n</i>) · [Source](https://github.com/d3/d3-interpolate/blob/master/src/quantize.js), [Examples](https://observablehq.com/@d3/d3-quantize)
Returns *n* uniformly-spaced samples from the specified *interpolator*, where *n* is an integer greater than one. The first sample is always at *t* = 0, and the last sample is always at *t* = 1. This can be useful in generating a fixed number of samples from a given interpolator, such as to derive the range of a [quantize scale](https://github.com/d3/d3-scale/blob/master/README.md#quantize-scales) from a [continuous interpolator](https://github.com/d3/d3-scale-chromatic/blob/master/README.md#interpolateWarm).
Caution: this method will not work with interpolators that do not return defensive copies of their output, such as [d3.interpolateArray](#interpolateArray), [d3.interpolateDate](#interpolateDate) and [d3.interpolateObject](#interpolateObject). For those interpolators, you must wrap the interpolator and create a copy for each returned value.
### Color Spaces
<a name="interpolateRgb" href="#interpolateRgb">#</a> d3.<b>interpolateRgb</b>(<i>a</i>, <i>b</i>) · [Source](https://github.com/d3/d3-interpolate/blob/master/src/rgb.js), [Examples](https://observablehq.com/@d3/working-with-color)
<img src="https://raw.githubusercontent.com/d3/d3-interpolate/master/img/rgb.png" width="100%" height="40" alt="rgb">
Or, with a corrected [gamma](#interpolate_gamma) of 2.2:
<img src="https://raw.githubusercontent.com/d3/d3-interpolate/master/img/rgbGamma.png" width="100%" height="40" alt="rgbGamma">
Returns an RGB color space interpolator between the two colors *a* and *b* with a configurable [gamma](#interpolate_gamma). If the gamma is not specified, it defaults to 1.0. The colors *a* and *b* need not be in RGB; they will be converted to RGB using [d3.rgb](https://github.com/d3/d3-color/blob/master/README.md#rgb). The return value of the interpolator is an RGB string.
<a href="#interpolateRgbBasis" name="interpolateRgbBasis">#</a> d3.<b>interpolateRgbBasis</b>(<i>colors</i>) · [Source](https://github.com/d3/d3-interpolate/blob/master/src/rgb.js#L54), [Examples](https://observablehq.com/@d3/working-with-color)
Returns a uniform nonrational B-spline interpolator through the specified array of *colors*, which are converted to [RGB color space](https://github.com/d3/d3-color/blob/master/README.md#rgb). Implicit control points are generated such that the interpolator returns *colors*[0] at *t* = 0 and *colors*[*colors*.length - 1] at *t* = 1. Opacity interpolation is not currently supported. See also [d3.interpolateBasis](#interpolateBasis), and see [d3-scale-chromatic](https://github.com/d3/d3-scale-chromatic) for examples.
<a href="#interpolateRgbBasisClosed" name="interpolateRgbBasisClosed">#</a> d3.<b>interpolateRgbBasisClosed</b>(<i>colors</i>) · [Source](https://github.com/d3/d3-interpolate/blob/master/src/rgb.js#L55), [Examples](https://observablehq.com/@d3/working-with-color)
Returns a uniform nonrational B-spline interpolator through the specified array of *colors*, which are converted to [RGB color space](https://github.com/d3/d3-color/blob/master/README.md#rgb). The control points are implicitly repeated such that the resulting spline has cyclical C² continuity when repeated around *t* in [0,1]; this is useful, for example, to create cyclical color scales. Opacity interpolation is not currently supported. See also [d3.interpolateBasisClosed](#interpolateBasisClosed), and see [d3-scale-chromatic](https://github.com/d3/d3-scale-chromatic) for examples.
<a name="interpolateHsl" href="#interpolateHsl">#</a> d3.<b>interpolateHsl</b>(<i>a</i>, <i>b</i>) · [Source](https://github.com/d3/d3-interpolate/blob/master/src/hsl.js), [Examples](https://observablehq.com/@d3/working-with-color)
<img src="https://raw.githubusercontent.com/d3/d3-interpolate/master/img/hsl.png" width="100%" height="40" alt="hsl">
Returns an HSL color space interpolator between the two colors *a* and *b*. The colors *a* and *b* need not be in HSL; they will be converted to HSL using [d3.hsl](https://github.com/d3/d3-color/blob/master/README.md#hsl). If either colors hue or saturation is NaN, the opposing colors channel value is used. The shortest path between hues is used. The return value of the interpolator is an RGB string.
<a name="interpolateHslLong" href="#interpolateHslLong">#</a> d3.<b>interpolateHslLong</b>(<i>a</i>, <i>b</i>) · [Source](https://github.com/d3/d3-interpolate/blob/master/src/hsl.js#L21), [Examples](https://observablehq.com/@d3/working-with-color)
<img src="https://raw.githubusercontent.com/d3/d3-interpolate/master/img/hslLong.png" width="100%" height="40" alt="hslLong">
Like [interpolateHsl](#interpolateHsl), but does not use the shortest path between hues.
<a name="interpolateLab" href="#interpolateLab">#</a> d3.<b>interpolateLab</b>(<i>a</i>, <i>b</i>) · [Source](https://github.com/d3/d3-interpolate/blob/master/src/lab.js), [Examples](https://observablehq.com/@d3/working-with-color)
<img src="https://raw.githubusercontent.com/d3/d3-interpolate/master/img/lab.png" width="100%" height="40" alt="lab">
Returns a [CIELAB color space](https://en.wikipedia.org/wiki/Lab_color_space#CIELAB) interpolator between the two colors *a* and *b*. The colors *a* and *b* need not be in CIELAB; they will be converted to CIELAB using [d3.lab](https://github.com/d3/d3-color/blob/master/README.md#lab). The return value of the interpolator is an RGB string.
<a name="interpolateHcl" href="#interpolateHcl">#</a> d3.<b>interpolateHcl</b>(<i>a</i>, <i>b</i>) · [Source](https://github.com/d3/d3-interpolate/blob/master/src/hcl.js), [Examples](https://observablehq.com/@d3/working-with-color)
<img src="https://raw.githubusercontent.com/d3/d3-interpolate/master/img/hcl.png" width="100%" height="40" alt="hcl">
Returns a [CIELCh<sub>ab</sub> color space](https://en.wikipedia.org/wiki/CIELAB_color_space#Cylindrical_representation:_CIELCh_or_CIEHLC) interpolator between the two colors *a* and *b*. The colors *a* and *b* need not be in CIELCh<sub>ab</sub>; they will be converted to CIELCh<sub>ab</sub> using [d3.hcl](https://github.com/d3/d3-color/blob/master/README.md#hcl). If either colors hue or chroma is NaN, the opposing colors channel value is used. The shortest path between hues is used. The return value of the interpolator is an RGB string.
<a name="interpolateHclLong" href="#interpolateHclLong">#</a> d3.<b>interpolateHclLong</b>(<i>a</i>, <i>b</i>) · [Source](https://github.com/d3/d3-interpolate/blob/master/src/hcl.js#L21), [Examples](https://observablehq.com/@d3/working-with-color)
<img src="https://raw.githubusercontent.com/d3/d3-interpolate/master/img/hclLong.png" width="100%" height="40" alt="hclLong">
Like [interpolateHcl](#interpolateHcl), but does not use the shortest path between hues.
<a name="interpolateCubehelix" href="#interpolateCubehelix">#</a> d3.<b>interpolateCubehelix</b>(<i>a</i>, <i>b</i>) · [Source](https://github.com/d3/d3-interpolate/blob/master/src/cubehelix.js), [Examples](https://observablehq.com/@d3/working-with-color)
<img src="https://raw.githubusercontent.com/d3/d3-interpolate/master/img/cubehelix.png" width="100%" height="40" alt="cubehelix">
Or, with a [gamma](#interpolate_gamma) of 3.0 to emphasize high-intensity values:
<img src="https://raw.githubusercontent.com/d3/d3-interpolate/master/img/cubehelixGamma.png" width="100%" height="40" alt="cubehelixGamma">
Returns a Cubehelix color space interpolator between the two colors *a* and *b* using a configurable [gamma](#interpolate_gamma). If the gamma is not specified, it defaults to 1.0. The colors *a* and *b* need not be in Cubehelix; they will be converted to Cubehelix using [d3.cubehelix](https://github.com/d3/d3-color/blob/master/README.md#cubehelix). If either colors hue or saturation is NaN, the opposing colors channel value is used. The shortest path between hues is used. The return value of the interpolator is an RGB string.
<a name="interpolateCubehelixLong" href="#interpolateCubehelixLong">#</a> d3.<b>interpolateCubehelixLong</b>(<i>a</i>, <i>b</i>) · [Source](https://github.com/d3/d3-interpolate/blob/master/src/cubehelix.js#L29), [Examples](https://observablehq.com/@d3/working-with-color)
<img src="https://raw.githubusercontent.com/d3/d3-interpolate/master/img/cubehelixLong.png" width="100%" height="40" alt="cubehelixLong">
Or, with a [gamma](#interpolate_gamma) of 3.0 to emphasize high-intensity values:
<img src="https://raw.githubusercontent.com/d3/d3-interpolate/master/img/cubehelixGammaLong.png" width="100%" height="40" alt="cubehelixGammaLong">
Like [interpolateCubehelix](#interpolateCubehelix), but does not use the shortest path between hues.
<a name="interpolate_gamma" href="#interpolate_gamma">#</a> <i>interpolate</i>.<b>gamma</b>(<i>gamma</i>)
Given that *interpolate* is one of [interpolateRgb](#interpolateRgb), [interpolateCubehelix](#interpolateCubehelix) or [interpolateCubehelixLong](#interpolateCubehelixLong), returns a new interpolator factory of the same type using the specified *gamma*. For example, to interpolate from purple to orange with a gamma of 2.2 in RGB space:
```js
const interpolator = d3.interpolateRgb.gamma(2.2)("purple", "orange");
```
See Eric Brasseurs article, [Gamma error in picture scaling](http://www.ericbrasseur.org/gamma.html), for more on gamma correction.
<a name="interpolateHue" href="#interpolateHue">#</a> d3.<b>interpolateHue</b>(<i>a</i>, <i>b</i>) · [Source](https://github.com/d3/d3-interpolate/blob/master/src/hue.js), [Examples](https://observablehq.com/@d3/working-with-color)
Returns an interpolator between the two hue angles *a* and *b*. If either hue is NaN, the opposing value is used. The shortest path between hues is used. The return value of the interpolator is a number in [0, 360).
### Splines
Whereas standard interpolators blend from a starting value *a* at *t* = 0 to an ending value *b* at *t* = 1, spline interpolators smoothly blend multiple input values for *t* in [0,1] using piecewise polynomial functions. Only cubic uniform nonrational [B-splines](https://en.wikipedia.org/wiki/B-spline) are currently supported, also known as basis splines.
<a href="#interpolateBasis" name="interpolateBasis">#</a> d3.<b>interpolateBasis</b>(<i>values</i>) · [Source](https://github.com/d3/d3-interpolate/blob/master/src/basis.js), [Examples](https://observablehq.com/@d3/d3-interpolatebasis)
Returns a uniform nonrational B-spline interpolator through the specified array of *values*, which must be numbers. Implicit control points are generated such that the interpolator returns *values*[0] at *t* = 0 and *values*[*values*.length - 1] at *t* = 1. See also [d3.curveBasis](https://github.com/d3/d3-shape/blob/master/README.md#curveBasis).
<a href="#interpolateBasisClosed" name="interpolateBasisClosed">#</a> d3.<b>interpolateBasisClosed</b>(<i>values</i>) · [Source](https://github.com/d3/d3-interpolate/blob/master/src/basisClosed.js), [Examples](https://observablehq.com/@d3/d3-interpolatebasis)
Returns a uniform nonrational B-spline interpolator through the specified array of *values*, which must be numbers. The control points are implicitly repeated such that the resulting one-dimensional spline has cyclical C² continuity when repeated around *t* in [0,1]. See also [d3.curveBasisClosed](https://github.com/d3/d3-shape/blob/master/README.md#curveBasisClosed).
### Piecewise
<a name="piecewise" href="#piecewise">#</a> d3.<b>piecewise</b>([<i>interpolate</i>, ]<i>values</i>) · [Source](https://github.com/d3/d3-interpolate/blob/master/src/piecewise.js), [Examples](https://observablehq.com/@d3/d3-piecewise)
Returns a piecewise interpolator, composing interpolators for each adjacent pair of *values*. The returned interpolator maps *t* in [0, 1 / (*n* - 1)] to *interpolate*(*values*[0], *values*[1]), *t* in [1 / (*n* - 1), 2 / (*n* - 1)] to *interpolate*(*values*[1], *values*[2]), and so on, where *n* = *values*.length. In effect, this is a lightweight [linear scale](https://github.com/d3/d3-scale/blob/master/README.md#linear-scales). For example, to blend through red, green and blue:
```js
const interpolate = d3.piecewise(d3.interpolateRgb.gamma(2.2), ["red", "green", "blue"]);
```
If *interpolate* is not specified, defaults to [d3.interpolate](#interpolate).

53
frontend/node_modules/d3-interpolate/package 2.json generated vendored Normal file
View File

@@ -0,0 +1,53 @@
{
"name": "d3-interpolate",
"version": "3.0.1",
"description": "Interpolate numbers, colors, strings, arrays, objects, whatever!",
"homepage": "https://d3js.org/d3-interpolate/",
"repository": {
"type": "git",
"url": "https://github.com/d3/d3-interpolate.git"
},
"keywords": [
"d3",
"d3-module",
"interpolate",
"interpolation",
"color"
],
"license": "ISC",
"author": {
"name": "Mike Bostock",
"url": "http://bost.ocks.org/mike"
},
"type": "module",
"files": [
"dist/**/*.js",
"src/**/*.js"
],
"module": "src/index.js",
"main": "src/index.js",
"jsdelivr": "dist/d3-interpolate.min.js",
"unpkg": "dist/d3-interpolate.min.js",
"exports": {
"umd": "./dist/d3-interpolate.min.js",
"default": "./src/index.js"
},
"sideEffects": false,
"dependencies": {
"d3-color": "1 - 3"
},
"devDependencies": {
"eslint": "7",
"mocha": "8",
"rollup": "2",
"rollup-plugin-terser": "7"
},
"scripts": {
"test": "mocha 'test/**/*-test.js' && eslint src test",
"prepublishOnly": "rm -rf dist && yarn test && rollup -c",
"postpublish": "git push && git push --tags && cd ../d3.github.com && git pull && cp ../${npm_package_name}/dist/${npm_package_name}.js ${npm_package_name}.v${npm_package_version%%.*}.js && cp ../${npm_package_name}/dist/${npm_package_name}.min.js ${npm_package_name}.v${npm_package_version%%.*}.min.js && git add ${npm_package_name}.v${npm_package_version%%.*}.js ${npm_package_name}.v${npm_package_version%%.*}.min.js && git commit -m \"${npm_package_name} ${npm_package_version}\" && git push && cd -"
},
"engines": {
"node": ">=12"
}
}

13
frontend/node_modules/d3-scale/LICENSE 2 generated vendored Normal file
View File

@@ -0,0 +1,13 @@
Copyright 2010-2021 Mike Bostock
Permission to use, copy, modify, and/or distribute this software for any purpose
with or without fee is hereby granted, provided that the above copyright notice
and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
THIS SOFTWARE.

1003
frontend/node_modules/d3-scale/README 2.md generated vendored Normal file

File diff suppressed because it is too large Load Diff

57
frontend/node_modules/d3-scale/package 2.json generated vendored Normal file
View File

@@ -0,0 +1,57 @@
{
"name": "d3-scale",
"version": "4.0.2",
"description": "Encodings that map abstract data to visual representation.",
"homepage": "https://d3js.org/d3-scale/",
"repository": {
"type": "git",
"url": "https://github.com/d3/d3-scale.git"
},
"keywords": [
"d3",
"d3-module",
"scale",
"visualization"
],
"license": "ISC",
"author": {
"name": "Mike Bostock",
"url": "https://bost.ocks.org/mike"
},
"type": "module",
"files": [
"dist/**/*.js",
"src/**/*.js"
],
"module": "src/index.js",
"main": "src/index.js",
"jsdelivr": "dist/d3-scale.min.js",
"unpkg": "dist/d3-scale.min.js",
"exports": {
"umd": "./dist/d3-scale.min.js",
"default": "./src/index.js"
},
"sideEffects": false,
"dependencies": {
"d3-array": "2.10.0 - 3",
"d3-format": "1 - 3",
"d3-interpolate": "1.2.0 - 3",
"d3-time": "2.1.1 - 3",
"d3-time-format": "2 - 4"
},
"devDependencies": {
"d3-color": "1 - 3",
"eslint": "7",
"mocha": "9",
"rollup": "2",
"rollup-plugin-terser": "7"
},
"scripts": {
"test": "TZ=America/Los_Angeles mocha 'test/**/*-test.js' && eslint src test",
"prepublishOnly": "rm -rf dist && yarn test && rollup -c",
"postpublish": "git push && git push --tags && cd ../d3.github.com && git pull && cp ../${npm_package_name}/dist/${npm_package_name}.js ${npm_package_name}.v${npm_package_version%%.*}.js && cp ../${npm_package_name}/dist/${npm_package_name}.min.js ${npm_package_name}.v${npm_package_version%%.*}.min.js && git add ${npm_package_name}.v${npm_package_version%%.*}.js ${npm_package_name}.v${npm_package_version%%.*}.min.js && git commit -m \"${npm_package_name} ${npm_package_version}\" && git push && cd -"
},
"engines": {
"node": ">=12"
}
}

13
frontend/node_modules/d3-shape/LICENSE 2 generated vendored Normal file
View File

@@ -0,0 +1,13 @@
Copyright 2010-2022 Mike Bostock
Permission to use, copy, modify, and/or distribute this software for any purpose
with or without fee is hereby granted, provided that the above copyright notice
and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
THIS SOFTWARE.

1227
frontend/node_modules/d3-shape/README 2.md generated vendored Normal file

File diff suppressed because it is too large Load Diff

55
frontend/node_modules/d3-shape/package 2.json generated vendored Normal file
View File

@@ -0,0 +1,55 @@
{
"name": "d3-shape",
"version": "3.2.0",
"description": "Graphical primitives for visualization, such as lines and areas.",
"homepage": "https://d3js.org/d3-shape/",
"repository": {
"type": "git",
"url": "https://github.com/d3/d3-shape.git"
},
"keywords": [
"d3",
"d3-module",
"graphics",
"visualization",
"canvas",
"svg"
],
"license": "ISC",
"author": {
"name": "Mike Bostock",
"url": "http://bost.ocks.org/mike"
},
"type": "module",
"files": [
"dist/**/*.js",
"src/**/*.js"
],
"module": "src/index.js",
"main": "src/index.js",
"jsdelivr": "dist/d3-shape.min.js",
"unpkg": "dist/d3-shape.min.js",
"exports": {
"umd": "./dist/d3-shape.min.js",
"default": "./src/index.js"
},
"sideEffects": false,
"dependencies": {
"d3-path": "^3.1.0"
},
"devDependencies": {
"d3-polygon": "1 - 3",
"eslint": "8",
"mocha": "10",
"rollup": "3",
"rollup-plugin-terser": "7"
},
"scripts": {
"test": "mocha 'test/**/*-test.js' && eslint src test",
"prepublishOnly": "rm -rf dist && rollup -c",
"postpublish": "git push && git push --tags && cd ../d3.github.com && git pull && cp ../${npm_package_name}/dist/${npm_package_name}.js ${npm_package_name}.v${npm_package_version%%.*}.js && cp ../${npm_package_name}/dist/${npm_package_name}.min.js ${npm_package_name}.v${npm_package_version%%.*}.min.js && git add ${npm_package_name}.v${npm_package_version%%.*}.js ${npm_package_name}.v${npm_package_version%%.*}.min.js && git commit -m \"${npm_package_name} ${npm_package_version}\" && git push && cd -"
},
"engines": {
"node": ">=12"
}
}

21
frontend/node_modules/dom-helpers/LICENSE 2 generated vendored Normal file
View File

@@ -0,0 +1,21 @@
The MIT License (MIT)
Copyright (c) 2015 Jason Quense
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

70
frontend/node_modules/dom-helpers/README 2.md generated vendored Normal file
View File

@@ -0,0 +1,70 @@
# dom-helpers
tiny modular DOM lib for ie9+
## Install
```sh
npm i -S dom-helpers
```
Mostly just naive wrappers around common DOM API inconsistencies, Cross browser work is minimal and mostly taken from jQuery. This library doesn't do a lot to normalize behavior across browsers, it mostly seeks to provide a common interface, and eliminate the need to write the same damn `if (ie9)` statements in every project.
For example `on()` works in all browsers ie9+ but it uses the native event system so actual event oddities will continue to exist. If you need **robust** cross-browser support, use jQuery. If you are just tired of rewriting:
```js
if (document.addEventListener)
return (node, eventName, handler, capture) =>
node.addEventListener(eventName, handler, capture || false)
else if (document.attachEvent)
return (node, eventName, handler) =>
node.attachEvent('on' + eventName, handler)
```
over and over again, or you need a ok `getComputedStyle` polyfill but don't want to include all of jQuery, use this.
dom-helpers does expect certain, polyfillable, es5 features to be present for which you can use `es5-shim` where needed
The real advantage to this collection is that any method can be required individually, meaning bundlers like webpack will only include the exact methods you use. This is great for environments where jQuery doesn't make sense, such as `React` where you only occasionally need to do direct DOM manipulation.
All methods are exported as a flat namesapce
```js
var helpers = require('dom-helpers')
var offset = require('dom-helpers/offset')
// style is a function
require('dom-helpers/css')(node, { width: '40px' })
```
- dom-helpers
- `ownerDocument(element)`: returns the element's document owner
- `ownerWindow(element)`: returns the element's document window
- `activeElement`: return focused element safely
- `querySelectorAll(element, selector)`: optimized qsa, uses `getElementBy{Id|TagName|ClassName}` if it can.
- `contains(container, element)`
- `height(element, useClientHeight)`
- `width(element, useClientWidth)`
- `matches(element, selector)`
- `offset(element)` -> `{ top: Number, left: Number, height: Number, width: Number}`
- `offsetParent(element)`: return the parent node that the element is offset from
- `position(element, [offsetParent]`: return "offset" of the node to its offsetParent, optionally you can specify the offset parent if different than the "real" one
- `scrollTop(element, [value])`
- `scrollLeft(element, [value])`
- `scrollParent(element)`
- `addClass(element, className)`
- `removeClass(element, className)`
- `hasClass(element, className)`
- `toggleClass(element, className)`
- `style(element, propName)` or `style(element, objectOfPropValues)`
- `getComputedStyle(element)` -> `getPropertyValue(name)`
- `animate(node, properties, duration, easing, callback)` programmatically start css transitions
- `transitionEnd(node, handler, [duration], [padding])` listens for transition end, and ensures that the handler if called even if the transition fails to fire its end event. Will attempt to read duration from the element, otherwise one can be provided
- `addEventListener(node, eventName, handler, [options])`:
- `removeEventListener(node, eventName, handler, [options])`:
- `listen(node, eventName, handler, [options])`: wraps `addEventlistener` and returns a function that calls `removeEventListener` for you
- `filter(selector, fn)`: returns a function handler that only fires when the target matches or is contained in the selector ex: `on(list, 'click', filter('li > a', handler))`
- `requestAnimationFrame(cb)` returns an ID for canceling
- `cancelAnimationFrame(id)`
- `scrollbarSize([recalc])` returns the scrollbar's width size in pixels
- `scrollTo(element, [scrollParent])`

48
frontend/node_modules/dom-helpers/package 2.json generated vendored Normal file
View File

@@ -0,0 +1,48 @@
{
"name": "dom-helpers",
"version": "5.2.1",
"description": "tiny modular DOM lib for ie9+",
"author": {
"name": "Jason Quense",
"email": "monastic.panic@gmail.com"
},
"repository": {
"type": "git",
"url": "git+https://github.com/react-bootstrap/dom-helpers.git"
},
"license": "MIT",
"main": "cjs/index.js",
"types": "cjs/index.d.ts",
"module": "esm/index.js",
"keywords": [
"dom-helpers",
"react-component",
"dom",
"api",
"cross-browser",
"style",
"event",
"height",
"width",
"dom-helpers",
"class",
"classlist",
"css"
],
"publishConfig": {
"directory": "lib"
},
"release": {
"conventionalCommits": true
},
"dependencies": {
"@babel/runtime": "^7.8.7",
"csstype": "^3.0.2"
},
"bugs": {
"url": "https://github.com/react-bootstrap/dom-helpers/issues"
},
"readme": "ERROR: No README data found!",
"homepage": "https://github.com/react-bootstrap/dom-helpers#readme",
"_id": "dom-helpers@5.2.0"
}

5
frontend/node_modules/dunder-proto/.eslintrc 2 generated vendored Normal file
View File

@@ -0,0 +1,5 @@
{
"root": true,
"extends": "@ljharb",
}

13
frontend/node_modules/dunder-proto/.nycrc 2 generated vendored Normal file
View File

@@ -0,0 +1,13 @@
{
"all": true,
"check-coverage": false,
"reporter": ["text-summary", "text", "html", "json"],
"lines": 86,
"statements": 85.93,
"functions": 82.43,
"branches": 76.06,
"exclude": [
"coverage",
"test"
]
}

24
frontend/node_modules/dunder-proto/CHANGELOG 2.md generated vendored Normal file
View File

@@ -0,0 +1,24 @@
# Changelog
All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/)
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
## [v1.0.1](https://github.com/es-shims/dunder-proto/compare/v1.0.0...v1.0.1) - 2024-12-16
### Commits
- [Fix] do not crash when `--disable-proto=throw` [`6c367d9`](https://github.com/es-shims/dunder-proto/commit/6c367d919bc1604778689a297bbdbfea65752847)
- [Tests] ensure noproto tests only use the current version of dunder-proto [`b02365b`](https://github.com/es-shims/dunder-proto/commit/b02365b9cf889c4a2cac7be0c3cfc90a789af36c)
- [Dev Deps] update `@arethetypeswrong/cli`, `@types/tape` [`e3c5c3b`](https://github.com/es-shims/dunder-proto/commit/e3c5c3bd81cf8cef7dff2eca19e558f0e307f666)
- [Deps] update `call-bind-apply-helpers` [`19f1da0`](https://github.com/es-shims/dunder-proto/commit/19f1da028b8dd0d05c85bfd8f7eed2819b686450)
## v1.0.0 - 2024-12-06
### Commits
- Initial implementation, tests, readme, types [`a5b74b0`](https://github.com/es-shims/dunder-proto/commit/a5b74b0082f5270cb0905cd9a2e533cee7498373)
- Initial commit [`73fb5a3`](https://github.com/es-shims/dunder-proto/commit/73fb5a353b51ac2ab00c9fdeb0114daffd4c07a8)
- npm init [`80152dc`](https://github.com/es-shims/dunder-proto/commit/80152dc98155da4eb046d9f67a87ed96e8280a1d)
- Only apps should have lockfiles [`03e6660`](https://github.com/es-shims/dunder-proto/commit/03e6660a1d70dc401f3e217a031475ec537243dd)

21
frontend/node_modules/dunder-proto/LICENSE 2 generated vendored Normal file
View File

@@ -0,0 +1,21 @@
MIT License
Copyright (c) 2024 ECMAScript Shims
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

54
frontend/node_modules/dunder-proto/README 2.md generated vendored Normal file
View File

@@ -0,0 +1,54 @@
# dunder-proto <sup>[![Version Badge][npm-version-svg]][package-url]</sup>
[![github actions][actions-image]][actions-url]
[![coverage][codecov-image]][codecov-url]
[![License][license-image]][license-url]
[![Downloads][downloads-image]][downloads-url]
[![npm badge][npm-badge-png]][package-url]
If available, the `Object.prototype.__proto__` accessor and mutator, call-bound.
## Getting started
```sh
npm install --save dunder-proto
```
## Usage/Examples
```js
const assert = require('assert');
const getDunder = require('dunder-proto/get');
const setDunder = require('dunder-proto/set');
const obj = {};
assert.equal('toString' in obj, true);
assert.equal(getDunder(obj), Object.prototype);
setDunder(obj, null);
assert.equal('toString' in obj, false);
assert.equal(getDunder(obj), null);
```
## Tests
Clone the repo, `npm install`, and run `npm test`
[package-url]: https://npmjs.org/package/dunder-proto
[npm-version-svg]: https://versionbadg.es/es-shims/dunder-proto.svg
[deps-svg]: https://david-dm.org/es-shims/dunder-proto.svg
[deps-url]: https://david-dm.org/es-shims/dunder-proto
[dev-deps-svg]: https://david-dm.org/es-shims/dunder-proto/dev-status.svg
[dev-deps-url]: https://david-dm.org/es-shims/dunder-proto#info=devDependencies
[npm-badge-png]: https://nodei.co/npm/dunder-proto.png?downloads=true&stars=true
[license-image]: https://img.shields.io/npm/l/dunder-proto.svg
[license-url]: LICENSE
[downloads-image]: https://img.shields.io/npm/dm/dunder-proto.svg
[downloads-url]: https://npm-stat.com/charts.html?package=dunder-proto
[codecov-image]: https://codecov.io/gh/es-shims/dunder-proto/branch/main/graphs/badge.svg
[codecov-url]: https://app.codecov.io/gh/es-shims/dunder-proto/
[actions-image]: https://img.shields.io/endpoint?url=https://github-actions-badge-u3jn4tfpocch.runkit.sh/es-shims/dunder-proto
[actions-url]: https://github.com/es-shims/dunder-proto/actions

30
frontend/node_modules/dunder-proto/get 2.js generated vendored Normal file
View File

@@ -0,0 +1,30 @@
'use strict';
var callBind = require('call-bind-apply-helpers');
var gOPD = require('gopd');
var hasProtoAccessor;
try {
// eslint-disable-next-line no-extra-parens, no-proto
hasProtoAccessor = /** @type {{ __proto__?: typeof Array.prototype }} */ ([]).__proto__ === Array.prototype;
} catch (e) {
if (!e || typeof e !== 'object' || !('code' in e) || e.code !== 'ERR_PROTO_ACCESS') {
throw e;
}
}
// eslint-disable-next-line no-extra-parens
var desc = !!hasProtoAccessor && gOPD && gOPD(Object.prototype, /** @type {keyof typeof Object.prototype} */ ('__proto__'));
var $Object = Object;
var $getPrototypeOf = $Object.getPrototypeOf;
/** @type {import('./get')} */
module.exports = desc && typeof desc.get === 'function'
? callBind([desc.get])
: typeof $getPrototypeOf === 'function'
? /** @type {import('./get')} */ function getDunder(value) {
// eslint-disable-next-line eqeqeq
return $getPrototypeOf(value == null ? value : $Object(value));
}
: false;

5
frontend/node_modules/dunder-proto/get.d 2.ts generated vendored Normal file
View File

@@ -0,0 +1,5 @@
declare function getDunderProto(target: {}): object | null;
declare const x: false | typeof getDunderProto;
export = x;

76
frontend/node_modules/dunder-proto/package 2.json generated vendored Normal file
View File

@@ -0,0 +1,76 @@
{
"name": "dunder-proto",
"version": "1.0.1",
"description": "If available, the `Object.prototype.__proto__` accessor and mutator, call-bound",
"main": false,
"exports": {
"./get": "./get.js",
"./set": "./set.js",
"./package.json": "./package.json"
},
"sideEffects": false,
"scripts": {
"prepack": "npmignore --auto --commentLines=autogenerated",
"prepublish": "not-in-publish || npm run prepublishOnly",
"prepublishOnly": "safe-publish-latest",
"prelint": "evalmd README.md",
"lint": "eslint --ext=.js,.mjs .",
"postlint": "tsc -p . && attw -P",
"pretest": "npm run lint",
"tests-only": "nyc tape 'test/**/*.js'",
"test": "npm run tests-only",
"posttest": "npx npm@'>= 10.2' audit --production",
"version": "auto-changelog && git add CHANGELOG.md",
"postversion": "auto-changelog && git add CHANGELOG.md && git commit --no-edit --amend && git tag -f \"v$(node -e \"console.log(require('./package.json').version)\")\""
},
"repository": {
"type": "git",
"url": "git+https://github.com/es-shims/dunder-proto.git"
},
"author": "Jordan Harband <ljharb@gmail.com>",
"license": "MIT",
"bugs": {
"url": "https://github.com/es-shims/dunder-proto/issues"
},
"homepage": "https://github.com/es-shims/dunder-proto#readme",
"dependencies": {
"call-bind-apply-helpers": "^1.0.1",
"es-errors": "^1.3.0",
"gopd": "^1.2.0"
},
"devDependencies": {
"@arethetypeswrong/cli": "^0.17.1",
"@ljharb/eslint-config": "^21.1.1",
"@ljharb/tsconfig": "^0.2.2",
"@types/tape": "^5.7.0",
"auto-changelog": "^2.5.0",
"encoding": "^0.1.13",
"eslint": "=8.8.0",
"evalmd": "^0.0.19",
"in-publish": "^2.0.1",
"npmignore": "^0.3.1",
"nyc": "^10.3.2",
"safe-publish-latest": "^2.0.0",
"tape": "^5.9.0",
"typescript": "next"
},
"auto-changelog": {
"output": "CHANGELOG.md",
"template": "keepachangelog",
"unreleased": false,
"commitLimit": false,
"backfillLimit": false,
"hideCredit": true
},
"testling": {
"files": "test/index.js"
},
"publishConfig": {
"ignore": [
".github/workflows"
]
},
"engines": {
"node": ">= 0.4"
}
}

35
frontend/node_modules/dunder-proto/set 2.js generated vendored Normal file
View File

@@ -0,0 +1,35 @@
'use strict';
var callBind = require('call-bind-apply-helpers');
var gOPD = require('gopd');
var $TypeError = require('es-errors/type');
/** @type {{ __proto__?: object | null }} */
var obj = {};
try {
obj.__proto__ = null; // eslint-disable-line no-proto
} catch (e) {
if (!e || typeof e !== 'object' || !('code' in e) || e.code !== 'ERR_PROTO_ACCESS') {
throw e;
}
}
var hasProtoMutator = !('toString' in obj);
// eslint-disable-next-line no-extra-parens
var desc = gOPD && gOPD(Object.prototype, /** @type {keyof typeof Object.prototype} */ ('__proto__'));
/** @type {import('./set')} */
module.exports = hasProtoMutator && (
// eslint-disable-next-line no-extra-parens
(!!desc && typeof desc.set === 'function' && /** @type {import('./set')} */ (callBind([desc.set])))
|| /** @type {import('./set')} */ function setDunder(object, proto) {
// this is node v0.10 or older, which doesn't have Object.setPrototypeOf and has undeniable __proto__
if (object == null) { // eslint-disable-line eqeqeq
throw new $TypeError('set Object.prototype.__proto__ called on null or undefined');
}
// eslint-disable-next-line no-proto, no-param-reassign, no-extra-parens
/** @type {{ __proto__?: object | null }} */ (object).__proto__ = proto;
return proto;
}
);

5
frontend/node_modules/dunder-proto/set.d 2.ts generated vendored Normal file
View File

@@ -0,0 +1,5 @@
declare function setDunderProto<P extends null | object>(target: {}, proto: P): P;
declare const x: false | typeof setDunderProto;
export = x;

9
frontend/node_modules/dunder-proto/tsconfig 2.json generated vendored Normal file
View File

@@ -0,0 +1,9 @@
{
"extends": "@ljharb/tsconfig",
"compilerOptions": {
"target": "ES2021",
},
"exclude": [
"coverage",
],
}

5
frontend/node_modules/electron-to-chromium/LICENSE 2 generated vendored Normal file
View File

@@ -0,0 +1,5 @@
Copyright 2018 Kilian Valkhof
Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted, provided that the above copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.

186
frontend/node_modules/electron-to-chromium/README 2.md generated vendored Normal file
View File

@@ -0,0 +1,186 @@
### Made by [@kilianvalkhof](https://twitter.com/kilianvalkhof)
#### Other projects:
- 💻 [Polypane](https://polypane.app) - Develop responsive websites and apps twice as fast on multiple screens at once
- 🖌️ [Superposition](https://superposition.design) - Kickstart your design system by extracting design tokens from your website
- 🗒️ [FromScratch](https://fromscratch.rocks) - A smart but simple autosaving scratchpad
---
# Electron-to-Chromium [![npm](https://img.shields.io/npm/v/electron-to-chromium.svg)](https://www.npmjs.com/package/electron-to-chromium) [![travis](https://img.shields.io/travis/Kilian/electron-to-chromium/master.svg)](https://travis-ci.org/Kilian/electron-to-chromium) [![npm-downloads](https://img.shields.io/npm/dm/electron-to-chromium.svg)](https://www.npmjs.com/package/electron-to-chromium) [![codecov](https://codecov.io/gh/Kilian/electron-to-chromium/branch/master/graph/badge.svg)](https://codecov.io/gh/Kilian/electron-to-chromium)[![FOSSA Status](https://app.fossa.io/api/projects/git%2Bgithub.com%2FKilian%2Felectron-to-chromium.svg?type=shield)](https://app.fossa.io/projects/git%2Bgithub.com%2FKilian%2Felectron-to-chromium?ref=badge_shield)
This repository provides a mapping of Electron versions to the Chromium version that it uses.
This package is used in [Browserslist](https://github.com/ai/browserslist), so you can use e.g. `electron >= 1.4` in [Autoprefixer](https://github.com/postcss/autoprefixer), [Stylelint](https://github.com/stylelint/stylelint), [babel-preset-env](https://github.com/babel/babel-preset-env) and [eslint-plugin-compat](https://github.com/amilajack/eslint-plugin-compat).
**Supported by:**
<a href="https://m.do.co/c/bb22ea58e765">
<img src="https://opensource.nyc3.cdn.digitaloceanspaces.com/attribution/assets/SVG/DO_Logo_horizontal_blue.svg" width="201px">
</a>
## Install
Install using `npm install electron-to-chromium`.
## Usage
To include Electron-to-Chromium, require it:
```js
var e2c = require('electron-to-chromium');
```
### Properties
The Electron-to-Chromium object has 4 properties to use:
#### `versions`
An object of key-value pairs with a _major_ Electron version as the key, and the corresponding major Chromium version as the value.
```js
var versions = e2c.versions;
console.log(versions['1.4']);
// returns "53"
```
#### `fullVersions`
An object of key-value pairs with a Electron version as the key, and the corresponding full Chromium version as the value.
```js
var versions = e2c.fullVersions;
console.log(versions['1.4.11']);
// returns "53.0.2785.143"
```
#### `chromiumVersions`
An object of key-value pairs with a _major_ Chromium version as the key, and the corresponding major Electron version as the value.
```js
var versions = e2c.chromiumVersions;
console.log(versions['54']);
// returns "1.4"
```
#### `fullChromiumVersions`
An object of key-value pairs with a Chromium version as the key, and an array of the corresponding major Electron versions as the value.
```js
var versions = e2c.fullChromiumVersions;
console.log(versions['54.0.2840.101']);
// returns ["1.5.1", "1.5.0"]
```
### Functions
#### `electronToChromium(query)`
Arguments:
* Query: string or number, required. A major or full Electron version.
A function that returns the corresponding Chromium version for a given Electron function. Returns a string.
If you provide it with a major Electron version, it will return a major Chromium version:
```js
var chromeVersion = e2c.electronToChromium('1.4');
// chromeVersion is "53"
```
If you provide it with a full Electron version, it will return the full Chromium version.
```js
var chromeVersion = e2c.electronToChromium('1.4.11');
// chromeVersion is "53.0.2785.143"
```
If a query does not match a Chromium version, it will return `undefined`.
```js
var chromeVersion = e2c.electronToChromium('9000');
// chromeVersion is undefined
```
#### `chromiumToElectron(query)`
Arguments:
* Query: string or number, required. A major or full Chromium version.
Returns a string with the corresponding Electron version for a given Chromium query.
If you provide it with a major Chromium version, it will return a major Electron version:
```js
var electronVersion = e2c.chromiumToElectron('54');
// electronVersion is "1.4"
```
If you provide it with a full Chrome version, it will return an array of full Electron versions.
```js
var electronVersions = e2c.chromiumToElectron('56.0.2924.87');
// electronVersions is ["1.6.3", "1.6.2", "1.6.1", "1.6.0"]
```
If a query does not match an Electron version, it will return `undefined`.
```js
var electronVersion = e2c.chromiumToElectron('10');
// electronVersion is undefined
```
#### `electronToBrowserList(query)` **DEPRECATED**
Arguments:
* Query: string or number, required. A major Electron version.
_**Deprecated**: Browserlist already includes electron-to-chromium._
A function that returns a [Browserslist](https://github.com/ai/browserslist) query that matches the given major Electron version. Returns a string.
If you provide it with a major Electron version, it will return a Browserlist query string that matches the Chromium capabilities:
```js
var query = e2c.electronToBrowserList('1.4');
// query is "Chrome >= 53"
```
If a query does not match a Chromium version, it will return `undefined`.
```js
var query = e2c.electronToBrowserList('9000');
// query is undefined
```
### Importing just versions, fullVersions, chromiumVersions and fullChromiumVersions
All lists can be imported on their own, if file size is a concern.
#### `versions`
```js
var versions = require('electron-to-chromium/versions');
```
#### `fullVersions`
```js
var fullVersions = require('electron-to-chromium/full-versions');
```
#### `chromiumVersions`
```js
var chromiumVersions = require('electron-to-chromium/chromium-versions');
```
#### `fullChromiumVersions`
```js
var fullChromiumVersions = require('electron-to-chromium/full-chromium-versions');
```
## Updating
This package will be updated with each new Electron release.
To update the list, run `npm run build.js`. Requires internet access as it downloads from the canonical list of Electron versions.
To verify correct behaviour, run `npm test`.
## License
[![FOSSA Status](https://app.fossa.io/api/projects/git%2Bgithub.com%2FKilian%2Felectron-to-chromium.svg?type=large)](https://app.fossa.io/projects/git%2Bgithub.com%2FKilian%2Felectron-to-chromium?ref=badge_large)

View File

@@ -0,0 +1,87 @@
module.exports = {
"39": "0.20",
"40": "0.21",
"41": "0.21",
"42": "0.25",
"43": "0.27",
"44": "0.30",
"45": "0.31",
"47": "0.36",
"49": "0.37",
"50": "1.1",
"51": "1.2",
"52": "1.3",
"53": "1.4",
"54": "1.4",
"56": "1.6",
"58": "1.7",
"59": "1.8",
"61": "2.0",
"66": "3.0",
"69": "4.0",
"72": "5.0",
"73": "5.0",
"76": "6.0",
"78": "7.0",
"79": "8.0",
"80": "8.0",
"82": "9.0",
"83": "9.0",
"84": "10.0",
"85": "10.0",
"86": "11.0",
"87": "11.0",
"89": "12.0",
"90": "13.0",
"91": "13.0",
"92": "14.0",
"93": "14.0",
"94": "15.0",
"95": "16.0",
"96": "16.0",
"98": "17.0",
"99": "18.0",
"100": "18.0",
"102": "19.0",
"103": "20.0",
"104": "20.0",
"105": "21.0",
"106": "21.0",
"107": "22.0",
"108": "22.0",
"110": "23.0",
"111": "24.0",
"112": "24.0",
"114": "25.0",
"116": "26.0",
"118": "27.0",
"119": "28.0",
"120": "28.0",
"121": "29.0",
"122": "29.0",
"123": "30.0",
"124": "30.0",
"125": "31.0",
"126": "31.0",
"127": "32.0",
"128": "32.0",
"129": "33.0",
"130": "33.0",
"131": "34.0",
"132": "34.0",
"133": "35.0",
"134": "35.0",
"135": "36.0",
"136": "36.0",
"137": "37.0",
"138": "37.0",
"139": "38.0",
"140": "38.0",
"141": "39.0",
"142": "39.0",
"143": "40.0",
"144": "40.0",
"146": "41.0",
"147": "42.0",
"148": "42.0"
};

View File

@@ -0,0 +1 @@
{"39":"0.20","40":"0.21","41":"0.21","42":"0.25","43":"0.27","44":"0.30","45":"0.31","47":"0.36","49":"0.37","50":"1.1","51":"1.2","52":"1.3","53":"1.4","54":"1.4","56":"1.6","58":"1.7","59":"1.8","61":"2.0","66":"3.0","69":"4.0","72":"5.0","73":"5.0","76":"6.0","78":"7.0","79":"8.0","80":"8.0","82":"9.0","83":"9.0","84":"10.0","85":"10.0","86":"11.0","87":"11.0","89":"12.0","90":"13.0","91":"13.0","92":"14.0","93":"14.0","94":"15.0","95":"16.0","96":"16.0","98":"17.0","99":"18.0","100":"18.0","102":"19.0","103":"20.0","104":"20.0","105":"21.0","106":"21.0","107":"22.0","108":"22.0","110":"23.0","111":"24.0","112":"24.0","114":"25.0","116":"26.0","118":"27.0","119":"28.0","120":"28.0","121":"29.0","122":"29.0","123":"30.0","124":"30.0","125":"31.0","126":"31.0","127":"32.0","128":"32.0","129":"33.0","130":"33.0","131":"34.0","132":"34.0","133":"35.0","134":"35.0","135":"36.0","136":"36.0","137":"37.0","138":"37.0","139":"38.0","140":"38.0","141":"39.0","142":"39.0","143":"40.0","144":"40.0","146":"41.0","147":"42.0","148":"42.0"}

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

36
frontend/node_modules/electron-to-chromium/index 2.js generated vendored Normal file
View File

@@ -0,0 +1,36 @@
var versions = require('./versions');
var fullVersions = require('./full-versions');
var chromiumVersions = require('./chromium-versions');
var fullChromiumVersions = require('./full-chromium-versions');
var electronToChromium = function (query) {
var number = getQueryString(query);
return number.split('.').length > 2 ? fullVersions[number] : versions[number] || undefined;
};
var chromiumToElectron = function (query) {
var number = getQueryString(query);
return number.split('.').length > 2 ? fullChromiumVersions[number] : chromiumVersions[number] || undefined;
};
var electronToBrowserList = function (query) {
var number = getQueryString(query);
return versions[number] ? "Chrome >= " + versions[number] : undefined;
};
var getQueryString = function (query) {
var number = query;
if (query === 1) { number = "1.0" }
if (typeof query === 'number') { number += ''; }
return number;
};
module.exports = {
versions: versions,
fullVersions: fullVersions,
chromiumVersions: chromiumVersions,
fullChromiumVersions: fullChromiumVersions,
electronToChromium: electronToChromium,
electronToBrowserList: electronToBrowserList,
chromiumToElectron: chromiumToElectron
};

View File

@@ -0,0 +1,44 @@
{
"name": "electron-to-chromium",
"version": "1.5.321",
"description": "Provides a list of electron-to-chromium version mappings",
"main": "index.js",
"files": [
"versions.js",
"full-versions.js",
"chromium-versions.js",
"full-chromium-versions.js",
"versions.json",
"full-versions.json",
"chromium-versions.json",
"full-chromium-versions.json",
"LICENSE"
],
"scripts": {
"build": "node build.mjs",
"update": "node automated-update.js",
"test": "nyc ava --verbose",
"report": "nyc report --reporter=text-lcov > coverage.lcov && codecov"
},
"repository": {
"type": "git",
"url": "git+https://github.com/kilian/electron-to-chromium.git"
},
"keywords": [
"electron",
"chrome",
"chromium",
"browserslist",
"browserlist"
],
"author": "Kilian Valkhof",
"license": "ISC",
"devDependencies": {
"ava": "^5.1.1",
"codecov": "^3.8.2",
"compare-versions": "^6.0.0-rc.1",
"node-fetch": "^3.3.0",
"nyc": "^15.1.0",
"shelljs": "^0.8.5"
}
}

View File

@@ -0,0 +1,241 @@
module.exports = {
"0.20": "39",
"0.21": "41",
"0.22": "41",
"0.23": "41",
"0.24": "41",
"0.25": "42",
"0.26": "42",
"0.27": "43",
"0.28": "43",
"0.29": "43",
"0.30": "44",
"0.31": "45",
"0.32": "45",
"0.33": "45",
"0.34": "45",
"0.35": "45",
"0.36": "47",
"0.37": "49",
"1.0": "49",
"1.1": "50",
"1.2": "51",
"1.3": "52",
"1.4": "53",
"1.5": "54",
"1.6": "56",
"1.7": "58",
"1.8": "59",
"2.0": "61",
"2.1": "61",
"3.0": "66",
"3.1": "66",
"4.0": "69",
"4.1": "69",
"4.2": "69",
"5.0": "73",
"6.0": "76",
"6.1": "76",
"7.0": "78",
"7.1": "78",
"7.2": "78",
"7.3": "78",
"8.0": "80",
"8.1": "80",
"8.2": "80",
"8.3": "80",
"8.4": "80",
"8.5": "80",
"9.0": "83",
"9.1": "83",
"9.2": "83",
"9.3": "83",
"9.4": "83",
"10.0": "85",
"10.1": "85",
"10.2": "85",
"10.3": "85",
"10.4": "85",
"11.0": "87",
"11.1": "87",
"11.2": "87",
"11.3": "87",
"11.4": "87",
"11.5": "87",
"12.0": "89",
"12.1": "89",
"12.2": "89",
"13.0": "91",
"13.1": "91",
"13.2": "91",
"13.3": "91",
"13.4": "91",
"13.5": "91",
"13.6": "91",
"14.0": "93",
"14.1": "93",
"14.2": "93",
"15.0": "94",
"15.1": "94",
"15.2": "94",
"15.3": "94",
"15.4": "94",
"15.5": "94",
"16.0": "96",
"16.1": "96",
"16.2": "96",
"17.0": "98",
"17.1": "98",
"17.2": "98",
"17.3": "98",
"17.4": "98",
"18.0": "100",
"18.1": "100",
"18.2": "100",
"18.3": "100",
"19.0": "102",
"19.1": "102",
"20.0": "104",
"20.1": "104",
"20.2": "104",
"20.3": "104",
"21.0": "106",
"21.1": "106",
"21.2": "106",
"21.3": "106",
"21.4": "106",
"22.0": "108",
"22.1": "108",
"22.2": "108",
"22.3": "108",
"23.0": "110",
"23.1": "110",
"23.2": "110",
"23.3": "110",
"24.0": "112",
"24.1": "112",
"24.2": "112",
"24.3": "112",
"24.4": "112",
"24.5": "112",
"24.6": "112",
"24.7": "112",
"24.8": "112",
"25.0": "114",
"25.1": "114",
"25.2": "114",
"25.3": "114",
"25.4": "114",
"25.5": "114",
"25.6": "114",
"25.7": "114",
"25.8": "114",
"25.9": "114",
"26.0": "116",
"26.1": "116",
"26.2": "116",
"26.3": "116",
"26.4": "116",
"26.5": "116",
"26.6": "116",
"27.0": "118",
"27.1": "118",
"27.2": "118",
"27.3": "118",
"28.0": "120",
"28.1": "120",
"28.2": "120",
"28.3": "120",
"29.0": "122",
"29.1": "122",
"29.2": "122",
"29.3": "122",
"29.4": "122",
"30.0": "124",
"30.1": "124",
"30.2": "124",
"30.3": "124",
"30.4": "124",
"30.5": "124",
"31.0": "126",
"31.1": "126",
"31.2": "126",
"31.3": "126",
"31.4": "126",
"31.5": "126",
"31.6": "126",
"31.7": "126",
"32.0": "128",
"32.1": "128",
"32.2": "128",
"32.3": "128",
"33.0": "130",
"33.1": "130",
"33.2": "130",
"33.3": "130",
"33.4": "130",
"34.0": "132",
"34.1": "132",
"34.2": "132",
"34.3": "132",
"34.4": "132",
"34.5": "132",
"35.0": "134",
"35.1": "134",
"35.2": "134",
"35.3": "134",
"35.4": "134",
"35.5": "134",
"35.6": "134",
"35.7": "134",
"36.0": "136",
"36.1": "136",
"36.2": "136",
"36.3": "136",
"36.4": "136",
"36.5": "136",
"36.6": "136",
"36.7": "136",
"36.8": "136",
"36.9": "136",
"37.0": "138",
"37.1": "138",
"37.2": "138",
"37.3": "138",
"37.4": "138",
"37.5": "138",
"37.6": "138",
"37.7": "138",
"37.8": "138",
"37.9": "138",
"37.10": "138",
"38.0": "140",
"38.1": "140",
"38.2": "140",
"38.3": "140",
"38.4": "140",
"38.5": "140",
"38.6": "140",
"38.7": "140",
"38.8": "140",
"39.0": "142",
"39.1": "142",
"39.2": "142",
"39.3": "142",
"39.4": "142",
"39.5": "142",
"39.6": "142",
"39.7": "142",
"39.8": "142",
"40.0": "144",
"40.1": "144",
"40.2": "144",
"40.3": "144",
"40.4": "144",
"40.5": "144",
"40.6": "144",
"40.7": "144",
"40.8": "144",
"41.0": "146",
"42.0": "148"
};

View File

@@ -0,0 +1 @@
{"0.20":"39","0.21":"41","0.22":"41","0.23":"41","0.24":"41","0.25":"42","0.26":"42","0.27":"43","0.28":"43","0.29":"43","0.30":"44","0.31":"45","0.32":"45","0.33":"45","0.34":"45","0.35":"45","0.36":"47","0.37":"49","1.0":"49","1.1":"50","1.2":"51","1.3":"52","1.4":"53","1.5":"54","1.6":"56","1.7":"58","1.8":"59","2.0":"61","2.1":"61","3.0":"66","3.1":"66","4.0":"69","4.1":"69","4.2":"69","5.0":"73","6.0":"76","6.1":"76","7.0":"78","7.1":"78","7.2":"78","7.3":"78","8.0":"80","8.1":"80","8.2":"80","8.3":"80","8.4":"80","8.5":"80","9.0":"83","9.1":"83","9.2":"83","9.3":"83","9.4":"83","10.0":"85","10.1":"85","10.2":"85","10.3":"85","10.4":"85","11.0":"87","11.1":"87","11.2":"87","11.3":"87","11.4":"87","11.5":"87","12.0":"89","12.1":"89","12.2":"89","13.0":"91","13.1":"91","13.2":"91","13.3":"91","13.4":"91","13.5":"91","13.6":"91","14.0":"93","14.1":"93","14.2":"93","15.0":"94","15.1":"94","15.2":"94","15.3":"94","15.4":"94","15.5":"94","16.0":"96","16.1":"96","16.2":"96","17.0":"98","17.1":"98","17.2":"98","17.3":"98","17.4":"98","18.0":"100","18.1":"100","18.2":"100","18.3":"100","19.0":"102","19.1":"102","20.0":"104","20.1":"104","20.2":"104","20.3":"104","21.0":"106","21.1":"106","21.2":"106","21.3":"106","21.4":"106","22.0":"108","22.1":"108","22.2":"108","22.3":"108","23.0":"110","23.1":"110","23.2":"110","23.3":"110","24.0":"112","24.1":"112","24.2":"112","24.3":"112","24.4":"112","24.5":"112","24.6":"112","24.7":"112","24.8":"112","25.0":"114","25.1":"114","25.2":"114","25.3":"114","25.4":"114","25.5":"114","25.6":"114","25.7":"114","25.8":"114","25.9":"114","26.0":"116","26.1":"116","26.2":"116","26.3":"116","26.4":"116","26.5":"116","26.6":"116","27.0":"118","27.1":"118","27.2":"118","27.3":"118","28.0":"120","28.1":"120","28.2":"120","28.3":"120","29.0":"122","29.1":"122","29.2":"122","29.3":"122","29.4":"122","30.0":"124","30.1":"124","30.2":"124","30.3":"124","30.4":"124","30.5":"124","31.0":"126","31.1":"126","31.2":"126","31.3":"126","31.4":"126","31.5":"126","31.6":"126","31.7":"126","32.0":"128","32.1":"128","32.2":"128","32.3":"128","33.0":"130","33.1":"130","33.2":"130","33.3":"130","33.4":"130","34.0":"132","34.1":"132","34.2":"132","34.3":"132","34.4":"132","34.5":"132","35.0":"134","35.1":"134","35.2":"134","35.3":"134","35.4":"134","35.5":"134","35.6":"134","35.7":"134","36.0":"136","36.1":"136","36.2":"136","36.3":"136","36.4":"136","36.5":"136","36.6":"136","36.7":"136","36.8":"136","36.9":"136","37.0":"138","37.1":"138","37.2":"138","37.3":"138","37.4":"138","37.5":"138","37.6":"138","37.7":"138","37.8":"138","37.9":"138","37.10":"138","38.0":"140","38.1":"140","38.2":"140","38.3":"140","38.4":"140","38.5":"140","38.6":"140","38.7":"140","38.8":"140","39.0":"142","39.1":"142","39.2":"142","39.3":"142","39.4":"142","39.5":"142","39.6":"142","39.7":"142","39.8":"142","40.0":"144","40.1":"144","40.2":"144","40.3":"144","40.4":"144","40.5":"144","40.6":"144","40.7":"144","40.8":"144","41.0":"146","42.0":"148"}

13
frontend/node_modules/es-define-property/.eslintrc 2 generated vendored Normal file
View File

@@ -0,0 +1,13 @@
{
"root": true,
"extends": "@ljharb",
"rules": {
"new-cap": ["error", {
"capIsNewExceptions": [
"GetIntrinsic",
],
}],
},
}

9
frontend/node_modules/es-define-property/.nycrc 2 generated vendored Normal file
View File

@@ -0,0 +1,9 @@
{
"all": true,
"check-coverage": false,
"reporter": ["text-summary", "text", "html", "json"],
"exclude": [
"coverage",
"test"
]
}

View File

@@ -0,0 +1,29 @@
# Changelog
All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/)
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
## [v1.0.1](https://github.com/ljharb/es-define-property/compare/v1.0.0...v1.0.1) - 2024-12-06
### Commits
- [types] use shared tsconfig [`954a663`](https://github.com/ljharb/es-define-property/commit/954a66360326e508a0e5daa4b07493d58f5e110e)
- [actions] split out node 10-20, and 20+ [`3a8e84b`](https://github.com/ljharb/es-define-property/commit/3a8e84b23883f26ff37b3e82ff283834228e18c6)
- [Dev Deps] update `@ljharb/eslint-config`, `@ljharb/tsconfig`, `@types/get-intrinsic`, `@types/tape`, `auto-changelog`, `gopd`, `tape` [`86ae27b`](https://github.com/ljharb/es-define-property/commit/86ae27bb8cc857b23885136fad9cbe965ae36612)
- [Refactor] avoid using `get-intrinsic` [`02480c0`](https://github.com/ljharb/es-define-property/commit/02480c0353ef6118965282977c3864aff53d98b1)
- [Tests] replace `aud` with `npm audit` [`f6093ff`](https://github.com/ljharb/es-define-property/commit/f6093ff74ab51c98015c2592cd393bd42478e773)
- [Tests] configure testling [`7139e66`](https://github.com/ljharb/es-define-property/commit/7139e66959247a56086d9977359caef27c6849e7)
- [Dev Deps] update `tape` [`b901b51`](https://github.com/ljharb/es-define-property/commit/b901b511a75e001a40ce1a59fef7d9ffcfc87482)
- [Tests] fix types in tests [`469d269`](https://github.com/ljharb/es-define-property/commit/469d269fd141b1e773ec053a9fa35843493583e0)
- [Dev Deps] add missing peer dep [`733acfb`](https://github.com/ljharb/es-define-property/commit/733acfb0c4c96edf337e470b89a25a5b3724c352)
## v1.0.0 - 2024-02-12
### Commits
- Initial implementation, tests, readme, types [`3e154e1`](https://github.com/ljharb/es-define-property/commit/3e154e11a2fee09127220f5e503bf2c0a31dd480)
- Initial commit [`07d98de`](https://github.com/ljharb/es-define-property/commit/07d98de34a4dc31ff5e83a37c0c3f49e0d85cd50)
- npm init [`c4eb634`](https://github.com/ljharb/es-define-property/commit/c4eb6348b0d3886aac36cef34ad2ee0665ea6f3e)
- Only apps should have lockfiles [`7af86ec`](https://github.com/ljharb/es-define-property/commit/7af86ec1d311ec0b17fdfe616a25f64276903856)

21
frontend/node_modules/es-define-property/LICENSE 2 generated vendored Normal file
View File

@@ -0,0 +1,21 @@
MIT License
Copyright (c) 2024 Jordan Harband
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

49
frontend/node_modules/es-define-property/README 2.md generated vendored Normal file
View File

@@ -0,0 +1,49 @@
# es-define-property <sup>[![Version Badge][npm-version-svg]][package-url]</sup>
[![github actions][actions-image]][actions-url]
[![coverage][codecov-image]][codecov-url]
[![License][license-image]][license-url]
[![Downloads][downloads-image]][downloads-url]
[![npm badge][npm-badge-png]][package-url]
`Object.defineProperty`, but not IE 8's broken one.
## Example
```js
const assert = require('assert');
const $defineProperty = require('es-define-property');
if ($defineProperty) {
assert.equal($defineProperty, Object.defineProperty);
} else if (Object.defineProperty) {
assert.equal($defineProperty, false, 'this is IE 8');
} else {
assert.equal($defineProperty, false, 'this is an ES3 engine');
}
```
## Tests
Simply clone the repo, `npm install`, and run `npm test`
## Security
Please email [@ljharb](https://github.com/ljharb) or see https://tidelift.com/security if you have a potential security vulnerability to report.
[package-url]: https://npmjs.org/package/es-define-property
[npm-version-svg]: https://versionbadg.es/ljharb/es-define-property.svg
[deps-svg]: https://david-dm.org/ljharb/es-define-property.svg
[deps-url]: https://david-dm.org/ljharb/es-define-property
[dev-deps-svg]: https://david-dm.org/ljharb/es-define-property/dev-status.svg
[dev-deps-url]: https://david-dm.org/ljharb/es-define-property#info=devDependencies
[npm-badge-png]: https://nodei.co/npm/es-define-property.png?downloads=true&stars=true
[license-image]: https://img.shields.io/npm/l/es-define-property.svg
[license-url]: LICENSE
[downloads-image]: https://img.shields.io/npm/dm/es-define-property.svg
[downloads-url]: https://npm-stat.com/charts.html?package=es-define-property
[codecov-image]: https://codecov.io/gh/ljharb/es-define-property/branch/main/graphs/badge.svg
[codecov-url]: https://app.codecov.io/gh/ljharb/es-define-property/
[actions-image]: https://img.shields.io/endpoint?url=https://github-actions-badge-u3jn4tfpocch.runkit.sh/ljharb/es-define-property
[actions-url]: https://github.com/ljharb/es-define-property/actions

14
frontend/node_modules/es-define-property/index 2.js generated vendored Normal file
View File

@@ -0,0 +1,14 @@
'use strict';
/** @type {import('.')} */
var $defineProperty = Object.defineProperty || false;
if ($defineProperty) {
try {
$defineProperty({}, 'a', { value: 1 });
} catch (e) {
// IE 8 has a broken defineProperty
$defineProperty = false;
}
}
module.exports = $defineProperty;

View File

@@ -0,0 +1,3 @@
declare const defineProperty: false | typeof Object.defineProperty;
export = defineProperty;

View File

@@ -0,0 +1,81 @@
{
"name": "es-define-property",
"version": "1.0.1",
"description": "`Object.defineProperty`, but not IE 8's broken one.",
"main": "index.js",
"types": "./index.d.ts",
"exports": {
".": "./index.js",
"./package.json": "./package.json"
},
"sideEffects": false,
"scripts": {
"prepack": "npmignore --auto --commentLines=autogenerated",
"prepublish": "not-in-publish || npm run prepublishOnly",
"prepublishOnly": "safe-publish-latest",
"prelint": "evalmd README.md",
"lint": "eslint --ext=js,mjs .",
"postlint": "tsc -p .",
"pretest": "npm run lint",
"tests-only": "nyc tape 'test/**/*.js'",
"test": "npm run tests-only",
"posttest": "npx npm@'>= 10.2' audit --production",
"version": "auto-changelog && git add CHANGELOG.md",
"postversion": "auto-changelog && git add CHANGELOG.md && git commit --no-edit --amend && git tag -f \"v$(node -e \"console.log(require('./package.json').version)\")\""
},
"repository": {
"type": "git",
"url": "git+https://github.com/ljharb/es-define-property.git"
},
"keywords": [
"javascript",
"ecmascript",
"object",
"define",
"property",
"defineProperty",
"Object.defineProperty"
],
"author": "Jordan Harband <ljharb@gmail.com>",
"license": "MIT",
"bugs": {
"url": "https://github.com/ljharb/es-define-property/issues"
},
"homepage": "https://github.com/ljharb/es-define-property#readme",
"devDependencies": {
"@ljharb/eslint-config": "^21.1.1",
"@ljharb/tsconfig": "^0.2.2",
"@types/gopd": "^1.0.3",
"@types/tape": "^5.6.5",
"auto-changelog": "^2.5.0",
"encoding": "^0.1.13",
"eslint": "^8.8.0",
"evalmd": "^0.0.19",
"gopd": "^1.2.0",
"in-publish": "^2.0.1",
"npmignore": "^0.3.1",
"nyc": "^10.3.2",
"safe-publish-latest": "^2.0.0",
"tape": "^5.9.0",
"typescript": "next"
},
"engines": {
"node": ">= 0.4"
},
"testling": {
"files": "test/index.js"
},
"auto-changelog": {
"output": "CHANGELOG.md",
"template": "keepachangelog",
"unreleased": false,
"commitLimit": false,
"backfillLimit": false,
"hideCredit": true
},
"publishConfig": {
"ignore": [
".github/workflows"
]
}
}

Some files were not shown because too many files have changed in this diff Show More