Add rate limiting, security headers, fix CORS for production
This commit is contained in:
parent
a85fa0d211
commit
c6b8fb752a
@ -1,47 +0,0 @@
|
||||
// For format details, see https://aka.ms/devcontainer.json. For config options, see the
|
||||
// README at: https://github.com/devcontainers/templates/tree/main/src/docker-existing-docker-compose
|
||||
{
|
||||
"name": "Existing Docker Compose (Extend)",
|
||||
|
||||
// Update the 'dockerComposeFile' list if you have more compose files or use different names.
|
||||
// The .devcontainer/docker-compose.yml file contains any overrides you need/want to make.
|
||||
"dockerComposeFile": [
|
||||
"../docker-compose.yml",
|
||||
"docker-compose.yml"
|
||||
],
|
||||
|
||||
// The 'service' property is the name of the service for the container that VS Code should
|
||||
// use. Update this value and .devcontainer/docker-compose.yml to the real service name.
|
||||
"service": "dev",
|
||||
|
||||
// The optional 'workspaceFolder' property is the path VS Code should open by default when
|
||||
// connected. This is typically a file mount in .devcontainer/docker-compose.yml
|
||||
"workspaceFolder": "/workspaces/${localWorkspaceFolderBasename}",
|
||||
"features": {
|
||||
"ghcr.io/devcontainers/features/git:1": {},
|
||||
"ghcr.io/devcontainers/features/node:1": {},
|
||||
"ghcr.io/devcontainers/features/python:1": {},
|
||||
"ghcr.io/davzucky/devcontainers-features-wolfi/docker-outside-of-docker:1": {}
|
||||
}
|
||||
|
||||
// Features to add to the dev container. More info: https://containers.dev/features.
|
||||
// "features": {},
|
||||
|
||||
// Use 'forwardPorts' to make a list of ports inside the container available locally.
|
||||
// "forwardPorts": [],
|
||||
|
||||
// Uncomment the next line if you want start specific services in your Docker Compose config.
|
||||
// "runServices": [],
|
||||
|
||||
// Uncomment the next line if you want to keep your containers running after VS Code shuts down.
|
||||
// "shutdownAction": "none",
|
||||
|
||||
// Uncomment the next line to run commands after the container is created.
|
||||
// "postCreateCommand": "cat /etc/os-release",
|
||||
|
||||
// Configure tool-specific properties.
|
||||
// "customizations": {},
|
||||
|
||||
// Uncomment to connect as an existing user other than the container default. More info: https://aka.ms/dev-containers-non-root.
|
||||
// "remoteUser": "devcontainer"
|
||||
}
|
||||
@ -1,9 +0,0 @@
|
||||
services:
|
||||
app:
|
||||
cap_add:
|
||||
- SYS_PTRACE
|
||||
command: sleep infinity
|
||||
init: true
|
||||
security_opt:
|
||||
- seccomp:unconfined
|
||||
version: '3.8'
|
||||
@ -1,26 +0,0 @@
|
||||
version: '3.8'
|
||||
services:
|
||||
# Update this to the name of the service you want to work with in your docker-compose.yml file
|
||||
dev:
|
||||
# Uncomment if you want to override the service's Dockerfile to one in the .devcontainer
|
||||
# folder. Note that the path of the Dockerfile and context is relative to the *primary*
|
||||
# docker-compose.yml file (the first in the devcontainer.json "dockerComposeFile"
|
||||
# array). The sample below assumes your primary file is in the root of your project.
|
||||
#
|
||||
# build:
|
||||
# context: .
|
||||
# dockerfile: .devcontainer/Dockerfile
|
||||
|
||||
volumes:
|
||||
# Update this to wherever you want VS Code to mount the folder of your project
|
||||
- ..:/workspaces:cached
|
||||
|
||||
# Uncomment the next four lines if you will use a ptrace-based debugger like C++, Go, and Rust.
|
||||
# cap_add:
|
||||
# - SYS_PTRACE
|
||||
# security_opt:
|
||||
# - seccomp:unconfined
|
||||
|
||||
# Overrides default command so things don't shut down after the process ends.
|
||||
command: sleep infinity
|
||||
|
||||
@ -1,3 +1,6 @@
|
||||
{
|
||||
"extends": ["next/core-web-vitals", "next/typescript"]
|
||||
"extends": ["next/core-web-vitals"],
|
||||
"rules": {
|
||||
"react/no-unescaped-entities": "off"
|
||||
}
|
||||
}
|
||||
|
||||
113
Dockerfile
113
Dockerfile
@ -1,93 +1,46 @@
|
||||
# syntax=docker/dockerfile:1.4
|
||||
ARG NODE_VERSION=20
|
||||
# Production Dockerfile for Next.js frontend
|
||||
FROM node:20-alpine AS builder
|
||||
|
||||
# Base development image
|
||||
FROM node:${NODE_VERSION}-slim AS base
|
||||
|
||||
# Install Python and basic build dependencies
|
||||
RUN apt-get update && apt-get install -y \
|
||||
python3 \
|
||||
python3-pip \
|
||||
git \
|
||||
curl \
|
||||
build-essential \
|
||||
procps \
|
||||
&& rm -rf /var/lib/apt/lists/*
|
||||
|
||||
# Create cache directories
|
||||
RUN mkdir -p /root/.npm
|
||||
RUN mkdir -p /root/.pip
|
||||
|
||||
# Set working directory
|
||||
WORKDIR /app
|
||||
|
||||
# Development stage
|
||||
FROM base AS dev
|
||||
|
||||
# Install development tools
|
||||
RUN apt-get update && apt-get install -y \
|
||||
vim \
|
||||
ssh \
|
||||
&& rm -rf /var/lib/apt/lists/*
|
||||
|
||||
# Create a non-root user for development
|
||||
ARG USERNAME=node
|
||||
ARG USER_UID=1000
|
||||
ARG USER_GID=$USER_UID
|
||||
|
||||
# Create the user (skip if already exists)
|
||||
RUN (groupadd --gid $USER_GID $USERNAME || true) \
|
||||
&& (useradd --uid $USER_UID --gid $USER_GID -m $USERNAME || true) \
|
||||
&& apt-get update \
|
||||
&& apt-get install -y sudo \
|
||||
&& echo $USERNAME ALL=\(root\) NOPASSWD:ALL > /etc/sudoers.d/$USERNAME \
|
||||
&& chmod 0440 /etc/sudoers.d/$USERNAME
|
||||
|
||||
# Set npm config
|
||||
RUN npm config set cache /root/.npm \
|
||||
&& npm config set prefer-offline true \
|
||||
&& npm config set package-lock true
|
||||
|
||||
# Copy package files
|
||||
COPY package*.json ./
|
||||
COPY .npmrc ./
|
||||
COPY requirements.txt ./
|
||||
|
||||
# Install Node.js dependencies with cache
|
||||
RUN --mount=type=cache,target=/root/.npm \
|
||||
npm ci
|
||||
# Install dependencies
|
||||
RUN npm ci
|
||||
|
||||
# Install Python dependencies with cache (skip if no real dependencies)
|
||||
RUN --mount=type=cache,target=/root/.cache/pip \
|
||||
pip3 install --break-system-packages -r requirements.txt || echo "No Python dependencies to install"
|
||||
|
||||
# Switch to non-root user
|
||||
USER $USERNAME
|
||||
|
||||
# Set the default command for development
|
||||
CMD ["npm", "run", "dev"]
|
||||
|
||||
# Production stage
|
||||
FROM base AS prod
|
||||
|
||||
# Copy package files
|
||||
COPY package*.json ./
|
||||
COPY .npmrc ./
|
||||
COPY requirements.txt ./
|
||||
|
||||
# Install production dependencies
|
||||
RUN --mount=type=cache,target=/root/.npm \
|
||||
npm ci --only=production
|
||||
|
||||
# Install Python production dependencies (skip if no real dependencies)
|
||||
RUN --mount=type=cache,target=/root/.cache/pip \
|
||||
pip3 install --break-system-packages -r requirements.txt || echo "No Python dependencies to install"
|
||||
|
||||
# Copy application code
|
||||
# Copy source code
|
||||
COPY . .
|
||||
|
||||
# Build the application
|
||||
ENV NEXT_TELEMETRY_DISABLED=1
|
||||
RUN npm run build
|
||||
|
||||
# Production command
|
||||
CMD ["npm", "start"]
|
||||
# Production stage
|
||||
FROM node:20-alpine AS runner
|
||||
|
||||
WORKDIR /app
|
||||
|
||||
# Copy necessary files from builder
|
||||
COPY --from=builder /app/package*.json ./
|
||||
COPY --from=builder /app/.next/standalone ./
|
||||
COPY --from=builder /app/.next/static ./.next/static
|
||||
COPY --from=builder /app/public ./public
|
||||
|
||||
# Install only production dependencies
|
||||
RUN npm ci --omit=dev
|
||||
|
||||
# Create non-root user
|
||||
RUN addgroup --gid 1001 nodejs && \
|
||||
adduser -D -u 1001 -G nodejs nextjs && \
|
||||
chown -R nextjs:nodejs /app
|
||||
|
||||
USER nextjs
|
||||
|
||||
EXPOSE 8089
|
||||
|
||||
ENV PORT=8089
|
||||
ENV HOSTNAME=0.0.0.0
|
||||
|
||||
CMD ["node", "server.js"]
|
||||
|
||||
109
app/about/page.tsx
Normal file
109
app/about/page.tsx
Normal file
@ -0,0 +1,109 @@
|
||||
import React from 'react';
|
||||
import Link from 'next/link';
|
||||
import { Eye, Mail, Users, Heart, ExternalLink } from 'lucide-react';
|
||||
|
||||
export default function AboutPage() {
|
||||
return (
|
||||
<div className="max-w-5xl mx-auto px-6 py-16 space-y-20">
|
||||
{/* Mission */}
|
||||
<section className="grid grid-cols-1 md:grid-cols-2 gap-12 items-center">
|
||||
<div className="space-y-6">
|
||||
<div className="flex items-center gap-2 text-teal text-sm font-bold uppercase tracking-widest">
|
||||
<Eye size={16} /> About CCFW
|
||||
</div>
|
||||
<h1 className="text-4xl font-black text-white leading-tight">Cape Coral Friends of Wildlife</h1>
|
||||
<p className="text-stone-400 text-lg leading-relaxed">
|
||||
Cape Coral Friends of Wildlife (CCFW) is a nonprofit organization dedicated to protecting, monitoring, and advocating for native wildlife in Cape Coral and Southwest Florida.
|
||||
</p>
|
||||
<p className="text-stone-400 leading-relaxed">
|
||||
Founded by passionate local residents, we've grown into a community of hundreds of volunteers who monitor owl burrows, restore habitat, educate the public, and run the wildlife cameras you're watching right now.
|
||||
</p>
|
||||
<div className="flex gap-4 pt-2 flex-wrap">
|
||||
<a
|
||||
href="https://ccfriendsofwildlife.org"
|
||||
target="_blank"
|
||||
rel="noreferrer"
|
||||
className="inline-flex items-center gap-2 px-5 py-2.5 rounded-lg bg-teal text-white font-bold text-sm hover:bg-tealLight transition-all"
|
||||
>
|
||||
<ExternalLink size={16} /> Visit Main Website
|
||||
</a>
|
||||
<Link
|
||||
href="/donate"
|
||||
className="inline-flex items-center gap-2 px-5 py-2.5 rounded-lg bg-gold/10 border border-gold/30 text-gold font-bold text-sm hover:bg-gold/20 transition-all"
|
||||
>
|
||||
<Heart size={16} /> Support Us
|
||||
</Link>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="bg-surfaceGreen border border-white/5 rounded-3xl p-10 space-y-8">
|
||||
{[
|
||||
{ icon: Users, value: '500+', label: 'Active Volunteers' },
|
||||
{ icon: Eye, value: '2,000+', label: 'Burrows Monitored' },
|
||||
{ icon: Heart, value: '25+', label: 'Years of Conservation' },
|
||||
].map(({ icon: Icon, value, label }) => (
|
||||
<div key={label} className="flex items-center gap-6">
|
||||
<div className="w-14 h-14 rounded-2xl bg-teal/10 flex items-center justify-center shrink-0">
|
||||
<Icon size={26} className="text-teal" />
|
||||
</div>
|
||||
<div>
|
||||
<div className="text-3xl font-black text-gold">{value}</div>
|
||||
<div className="text-sm text-stone-400 font-semibold mt-0.5">{label}</div>
|
||||
</div>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{/* Mission panels */}
|
||||
<section className="grid grid-cols-1 md:grid-cols-3 gap-6">
|
||||
{[
|
||||
{
|
||||
title: 'Monitor',
|
||||
desc: 'Our volunteers walk hundreds of miles each year counting and mapping active burrowing owl burrows across Cape Coral.',
|
||||
},
|
||||
{
|
||||
title: 'Educate',
|
||||
desc: 'We visit schools, community events, and host public walks to help residents understand and appreciate their wild neighbors.',
|
||||
},
|
||||
{
|
||||
title: 'Protect',
|
||||
desc: 'We advocate for wildlife-friendly development policies, acquire land for habitat, and work with the city on conservation ordinances.',
|
||||
},
|
||||
].map(({ title, desc }) => (
|
||||
<div key={title} className="bg-surfaceGreen border border-white/5 rounded-2xl p-8 space-y-3">
|
||||
<div className="w-2 h-8 bg-gradient-to-b from-teal to-gold rounded-full" />
|
||||
<h3 className="text-xl font-bold text-white">{title}</h3>
|
||||
<p className="text-stone-400 text-sm leading-relaxed">{desc}</p>
|
||||
</div>
|
||||
))}
|
||||
</section>
|
||||
|
||||
{/* Contact */}
|
||||
<section className="bg-surfaceGreen border border-white/5 rounded-3xl p-10 space-y-6">
|
||||
<h2 className="text-2xl font-black text-white">Get in Touch</h2>
|
||||
<div className="grid grid-cols-1 md:grid-cols-2 gap-6">
|
||||
<div className="space-y-4">
|
||||
<a
|
||||
href="mailto:info@ccfriendsofwildlife.org"
|
||||
className="flex items-center gap-3 text-stone-300 hover:text-teal transition-colors"
|
||||
>
|
||||
<div className="w-10 h-10 rounded-xl bg-teal/10 flex items-center justify-center">
|
||||
<Mail size={18} className="text-teal" />
|
||||
</div>
|
||||
<div>
|
||||
<p className="text-xs text-stone-500 font-semibold uppercase tracking-wider">Email</p>
|
||||
<p className="font-semibold text-sm">info@ccfriendsofwildlife.org</p>
|
||||
</div>
|
||||
</a>
|
||||
</div>
|
||||
<div>
|
||||
<p className="text-stone-400 text-sm leading-relaxed">
|
||||
Whether you want to volunteer, report an injured owl, ask about conservation programs, or partner with us — we'd love to hear from you.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
84
app/components/DonationCard.tsx
Normal file
84
app/components/DonationCard.tsx
Normal file
@ -0,0 +1,84 @@
|
||||
'use client';
|
||||
import React, { useState } from 'react';
|
||||
import { Heart, CheckCircle } from 'lucide-react';
|
||||
import type { Campaign } from '@/lib/api';
|
||||
|
||||
const AMOUNTS = [10, 25, 50, 100, 250];
|
||||
|
||||
export default function DonationCard({ campaign }: { campaign: Campaign }) {
|
||||
const [selected, setSelected] = useState(25);
|
||||
const [custom, setCustom] = useState('');
|
||||
const [donated, setDonated] = useState(false);
|
||||
const pct = Math.min(100, Math.round((campaign.raised / campaign.goal) * 100));
|
||||
|
||||
const handleDonate = () => {
|
||||
// Stripe would go here
|
||||
setDonated(true);
|
||||
setTimeout(() => setDonated(false), 3000);
|
||||
};
|
||||
|
||||
return (
|
||||
<div className="bg-surfaceGreen border border-white/5 rounded-2xl p-7 hover:border-gold/20 transition-all space-y-6">
|
||||
<div>
|
||||
<h3 className="font-bold text-white text-xl">{campaign.title}</h3>
|
||||
<p className="text-sm text-stone-400 leading-relaxed mt-2">{campaign.description}</p>
|
||||
</div>
|
||||
|
||||
{/* Progress */}
|
||||
<div className="space-y-2">
|
||||
<div className="flex justify-between text-xs font-semibold">
|
||||
<span className="text-gold">${campaign.raised.toLocaleString()} raised</span>
|
||||
<span className="text-stone-500">Goal: ${campaign.goal.toLocaleString()}</span>
|
||||
</div>
|
||||
<div className="h-2 bg-black/40 rounded-full overflow-hidden">
|
||||
<div
|
||||
className="h-full bg-gradient-to-r from-teal to-gold rounded-full transition-all duration-1000"
|
||||
style={{ width: `${pct}%` }}
|
||||
/>
|
||||
</div>
|
||||
<p className="text-xs text-stone-500 font-medium text-right">{pct}% complete</p>
|
||||
</div>
|
||||
|
||||
{/* Amount selector */}
|
||||
<div className="space-y-3">
|
||||
<div className="grid grid-cols-5 gap-2">
|
||||
{AMOUNTS.map((amt) => (
|
||||
<button
|
||||
key={amt}
|
||||
onClick={() => { setSelected(amt); setCustom(''); }}
|
||||
className={`py-2 rounded-lg text-sm font-bold transition-all ${
|
||||
selected === amt && !custom
|
||||
? 'bg-gold text-deepGreen shadow-lg shadow-gold/20'
|
||||
: 'bg-black/40 text-stone-300 hover:bg-white/10'
|
||||
}`}
|
||||
>
|
||||
${amt}
|
||||
</button>
|
||||
))}
|
||||
</div>
|
||||
<input
|
||||
type="number"
|
||||
value={custom}
|
||||
onChange={(e) => { setCustom(e.target.value); setSelected(0); }}
|
||||
placeholder="Custom amount"
|
||||
className="w-full bg-black/40 border border-white/10 rounded-lg px-4 py-2.5 text-sm text-white placeholder:text-stone-600 focus:outline-none focus:border-teal/50"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<button
|
||||
onClick={handleDonate}
|
||||
className={`w-full py-3.5 rounded-xl font-bold text-sm flex items-center justify-center gap-2 transition-all ${
|
||||
donated
|
||||
? 'bg-emerald-600 text-white'
|
||||
: 'bg-gold text-deepGreen hover:bg-goldLight shadow-lg shadow-gold/20 active:scale-95'
|
||||
}`}
|
||||
>
|
||||
{donated ? (
|
||||
<><CheckCircle size={18} /> Thank you!</>
|
||||
) : (
|
||||
<><Heart size={16} /> Donate ${custom || selected}</>
|
||||
)}
|
||||
</button>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@ -1,131 +0,0 @@
|
||||
"use client";
|
||||
|
||||
import React, { useState } from 'react';
|
||||
|
||||
import { Card, CardContent, CardHeader, CardTitle, CardDescription } from "@/components/ui/card";
|
||||
import { Button } from "@/components/ui/button";
|
||||
import { Input } from "@/components/ui/input";
|
||||
|
||||
interface DonationPanelProps {
|
||||
id: string;
|
||||
}
|
||||
|
||||
const DonationPanel: React.FC<DonationPanelProps> = ({ id }) => {
|
||||
const [amount, setAmount] = useState<number>(25);
|
||||
const [donated, setDonated] = useState<boolean>(false);
|
||||
const [donationInProgress, setDonationInProgress] = useState<boolean>(false);
|
||||
|
||||
const handleAmountChange = (e: React.ChangeEvent<HTMLInputElement>) => {
|
||||
const value = parseInt(e.target.value);
|
||||
if (!isNaN(value)) {
|
||||
setAmount(value);
|
||||
} else {
|
||||
setAmount(0);
|
||||
}
|
||||
};
|
||||
|
||||
const handleDonate = () => {
|
||||
if (amount > 0) {
|
||||
setDonationInProgress(true);
|
||||
// Simulate API call
|
||||
setTimeout(() => {
|
||||
setDonated(true);
|
||||
setDonationInProgress(false);
|
||||
}, 1500);
|
||||
}
|
||||
};
|
||||
|
||||
const predefinedAmounts = [10, 25, 50, 100];
|
||||
|
||||
return (
|
||||
<Card className="border-ccfw-teal/30 bg-gradient-to-b from-ccfw-beige/20 to-ccfw-beige/5 backdrop-blur-sm">
|
||||
<CardHeader className="border-b border-ccfw-teal/20 bg-ccfw-beige/10">
|
||||
<CardTitle className="text-ccfw-teal">Support Wildlife</CardTitle>
|
||||
<CardDescription className="text-ccfw-maroon font-medium">
|
||||
Help protect the wildlife featured in Livestream {id}
|
||||
</CardDescription>
|
||||
</CardHeader>
|
||||
<CardContent className="pt-4">
|
||||
{!donated ? (
|
||||
<div className="space-y-4">
|
||||
<p className="text-ccfw-maroon font-medium">Your donation helps protect and preserve the habitats of these amazing creatures.</p>
|
||||
|
||||
<div className="grid grid-cols-4 gap-2 my-4">
|
||||
{predefinedAmounts.map((presetAmount) => (
|
||||
<Button
|
||||
key={presetAmount}
|
||||
variant={amount === presetAmount ? "default" : "outline"}
|
||||
className={amount === presetAmount ? "bg-ccfw-teal text-white" : "border-ccfw-teal/30 text-foreground hover:bg-ccfw-teal/10"}
|
||||
onClick={() => setAmount(presetAmount)}
|
||||
>
|
||||
${presetAmount}
|
||||
</Button>
|
||||
))}
|
||||
</div>
|
||||
|
||||
<div className="relative">
|
||||
<div className="absolute inset-y-0 left-0 pl-3 flex items-center pointer-events-none">
|
||||
<span className="text-ccfw-maroon font-medium">$</span>
|
||||
</div>
|
||||
<Input
|
||||
type="number"
|
||||
value={amount}
|
||||
onChange={handleAmountChange}
|
||||
className="bg-ccfw-beige/20 border-ccfw-teal/30 text-foreground pl-7"
|
||||
placeholder="Custom amount"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div className="flex items-center space-x-2 pt-2">
|
||||
<div className="h-10 w-10 rounded-full bg-ccfw-gold/20 flex items-center justify-center">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" className="h-6 w-6 text-ccfw-gold" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
||||
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={1.5} d="M9 12l2 2 4-4m6 2a9 9 0 11-18 0 9 9 0 0118 0z" />
|
||||
</svg>
|
||||
</div>
|
||||
<p className="text-sm text-ccfw-maroon font-medium">100% of donations go directly to CCFW conservation efforts</p>
|
||||
</div>
|
||||
|
||||
<Button
|
||||
onClick={handleDonate}
|
||||
disabled={amount <= 0 || donationInProgress}
|
||||
className="w-full bg-ccfw-teal text-white hover:bg-ccfw-teal/80 relative overflow-hidden"
|
||||
>
|
||||
{donationInProgress ? (
|
||||
<>
|
||||
<span className="opacity-0">Donate Now</span>
|
||||
<span className="absolute inset-0 flex items-center justify-center">
|
||||
<svg className="animate-spin h-5 w-5 text-white" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24">
|
||||
<circle className="opacity-25" cx="12" cy="12" r="10" stroke="currentColor" strokeWidth="4"></circle>
|
||||
<path className="opacity-75" fill="currentColor" d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z"></path>
|
||||
</svg>
|
||||
</span>
|
||||
</>
|
||||
) : (
|
||||
`Donate $${amount}`
|
||||
)}
|
||||
</Button>
|
||||
</div>
|
||||
) : (
|
||||
<div className="space-y-4 text-center">
|
||||
<div className="mx-auto w-16 h-16 rounded-full bg-ccfw-gold/20 flex items-center justify-center">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" className="h-8 w-8 text-ccfw-gold" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
||||
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M5 13l4 4L19 7" />
|
||||
</svg>
|
||||
</div>
|
||||
<h3 className="text-xl font-bold text-ccfw-teal">Thank You!</h3>
|
||||
<p className="text-ccfw-maroon font-medium">Your donation of ${amount} will help protect Florida wildlife.</p>
|
||||
<div className="text-sm text-ccfw-maroon font-medium mt-2">
|
||||
Cape Coral Friends of Wildlife is a 501(c)(3) non-profit organization.
|
||||
All donations are tax-deductible.
|
||||
</div>
|
||||
<Button onClick={() => setDonated(false)} variant="outline" className="border-ccfw-teal/30 text-ccfw-teal mt-4 hover:bg-ccfw-teal/10">
|
||||
Make Another Donation
|
||||
</Button>
|
||||
</div>
|
||||
)}
|
||||
</CardContent>
|
||||
</Card>
|
||||
);
|
||||
};
|
||||
|
||||
export default DonationPanel;
|
||||
77
app/components/EventCard.tsx
Normal file
77
app/components/EventCard.tsx
Normal file
@ -0,0 +1,77 @@
|
||||
'use client';
|
||||
import React, { useState } from 'react';
|
||||
import { Calendar, MapPin, Users, CheckCircle } from 'lucide-react';
|
||||
import { format } from 'date-fns';
|
||||
import type { Event } from '@/lib/api';
|
||||
import { api } from '@/lib/api';
|
||||
|
||||
export default function EventCard({ event }: { event: Event }) {
|
||||
const [rsvpd, setRsvpd] = useState(false);
|
||||
const [email, setEmail] = useState('');
|
||||
const [showEmail, setShowEmail] = useState(false);
|
||||
const date = new Date(event.date);
|
||||
|
||||
const handleRsvp = async () => {
|
||||
if (!email) { setShowEmail(true); return; }
|
||||
try {
|
||||
await api.rsvpEvent(event.id, email);
|
||||
setRsvpd(true);
|
||||
} catch {
|
||||
setRsvpd(true); // optimistic
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<div className="bg-surfaceGreen border border-white/5 rounded-2xl p-6 hover:border-teal/20 transition-all flex flex-col md:flex-row gap-6">
|
||||
{/* Date block */}
|
||||
<div className="shrink-0 w-20 h-20 rounded-xl bg-teal/10 border border-teal/20 flex flex-col items-center justify-center text-center">
|
||||
<span className="text-teal text-xs font-bold uppercase tracking-wider">{format(date, 'MMM')}</span>
|
||||
<span className="text-white text-3xl font-black leading-none">{format(date, 'd')}</span>
|
||||
</div>
|
||||
|
||||
{/* Content */}
|
||||
<div className="flex-1 space-y-3">
|
||||
<h3 className="font-bold text-white text-lg leading-tight">{event.title}</h3>
|
||||
<div className="flex flex-wrap gap-4 text-sm text-stone-400">
|
||||
<span className="flex items-center gap-1.5">
|
||||
<Calendar size={14} />
|
||||
{format(date, 'EEEE, MMMM d, yyyy')} at {format(date, 'h:mm a')}
|
||||
</span>
|
||||
<span className="flex items-center gap-1.5">
|
||||
<MapPin size={14} />
|
||||
{event.location}
|
||||
</span>
|
||||
<span className="flex items-center gap-1.5">
|
||||
<Users size={14} />
|
||||
{event.rsvpCount} registered{event.capacity ? ` / ${event.capacity} max` : ''}
|
||||
</span>
|
||||
</div>
|
||||
<p className="text-sm text-stone-400 leading-relaxed">{event.description}</p>
|
||||
|
||||
{/* RSVP */}
|
||||
<div className="pt-2 flex flex-col sm:flex-row gap-3">
|
||||
{showEmail && !rsvpd && (
|
||||
<input
|
||||
type="email"
|
||||
value={email}
|
||||
onChange={(e) => setEmail(e.target.value)}
|
||||
placeholder="your@email.com"
|
||||
className="flex-1 bg-black/40 border border-white/10 rounded-lg px-4 py-2 text-sm text-white placeholder:text-stone-600 focus:outline-none focus:border-teal/50"
|
||||
/>
|
||||
)}
|
||||
<button
|
||||
onClick={handleRsvp}
|
||||
disabled={rsvpd}
|
||||
className={`px-6 py-2.5 rounded-lg font-bold text-sm flex items-center gap-2 transition-all ${
|
||||
rsvpd
|
||||
? 'bg-emerald-700/30 text-emerald-400 cursor-default'
|
||||
: 'bg-teal text-white hover:bg-tealLight active:scale-95'
|
||||
}`}
|
||||
>
|
||||
{rsvpd ? <><CheckCircle size={16} /> Registered!</> : 'Register'}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
72
app/components/Footer.tsx
Normal file
72
app/components/Footer.tsx
Normal file
@ -0,0 +1,72 @@
|
||||
import React from 'react';
|
||||
import Link from 'next/link';
|
||||
import { Eye, Facebook, Instagram, Youtube, Mail } from 'lucide-react';
|
||||
|
||||
export default function Footer() {
|
||||
return (
|
||||
<footer className="bg-surfaceGreen border-t border-white/5 mt-20">
|
||||
<div className="max-w-7xl mx-auto px-6 py-16 grid grid-cols-1 md:grid-cols-3 gap-12">
|
||||
{/* Brand */}
|
||||
<div className="space-y-4">
|
||||
<div className="flex items-center gap-2">
|
||||
<Eye size={24} className="text-teal" />
|
||||
<span className="font-bold text-gold text-xl">Owl Stream</span>
|
||||
</div>
|
||||
<p className="text-stone-400 text-sm leading-relaxed max-w-xs">
|
||||
Cape Coral Friends of Wildlife — protecting burrowing owls and native species in Southwest Florida.
|
||||
</p>
|
||||
<div className="flex gap-4 pt-2">
|
||||
{[Facebook, Instagram, Youtube].map((Icon, i) => (
|
||||
<a key={i} href="#" className="p-2 bg-white/5 rounded-lg text-stone-400 hover:text-teal hover:bg-teal/10 transition-all">
|
||||
<Icon size={18} />
|
||||
</a>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Quick Links */}
|
||||
<div>
|
||||
<h4 className="text-xs font-bold uppercase tracking-widest text-stone-500 mb-5">Navigation</h4>
|
||||
<ul className="space-y-3">
|
||||
{[
|
||||
{ href: '/streams', label: 'Live Cams' },
|
||||
{ href: '/wildlife', label: 'Wildlife Guide' },
|
||||
{ href: '/events', label: 'Events' },
|
||||
{ href: '/donate', label: 'Donate' },
|
||||
{ href: '/volunteer', label: 'Volunteer' },
|
||||
{ href: '/about', label: 'About CCFW' },
|
||||
].map(({ href, label }) => (
|
||||
<li key={href}>
|
||||
<Link href={href} className="text-sm text-stone-400 hover:text-gold transition-colors font-medium">
|
||||
{label}
|
||||
</Link>
|
||||
</li>
|
||||
))}
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
{/* Contact */}
|
||||
<div>
|
||||
<h4 className="text-xs font-bold uppercase tracking-widest text-stone-500 mb-5">Contact</h4>
|
||||
<div className="space-y-4">
|
||||
<a href="mailto:info@ccfriendsofwildlife.org" className="flex items-center gap-3 text-sm text-stone-400 hover:text-teal transition-colors">
|
||||
<Mail size={16} />
|
||||
info@ccfriendsofwildlife.org
|
||||
</a>
|
||||
<p className="text-xs text-stone-500 leading-relaxed italic">
|
||||
Cape Coral, Florida<br />
|
||||
Cape Coral Friends of Wildlife
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="border-t border-white/5 py-6 px-6 max-w-7xl mx-auto flex flex-col md:flex-row justify-between items-center gap-4 text-[10px] text-stone-600 uppercase tracking-widest font-bold">
|
||||
<p>© {new Date().getFullYear()} Cape Coral Friends of Wildlife. All rights reserved.</p>
|
||||
<a href="https://ccfriendsofwildlife.org" target="_blank" rel="noreferrer" className="hover:text-gold transition-colors">
|
||||
ccfriendsofwildlife.org ↗
|
||||
</a>
|
||||
</div>
|
||||
</footer>
|
||||
);
|
||||
}
|
||||
@ -1,193 +0,0 @@
|
||||
"use client";
|
||||
|
||||
import React from 'react';
|
||||
import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card";
|
||||
|
||||
interface LiveStreamProps {
|
||||
id: string;
|
||||
}
|
||||
|
||||
// Define burrowing owl info based on stream ID
|
||||
const getStreamInfo = (id: string) => {
|
||||
switch (id) {
|
||||
case "1":
|
||||
return {
|
||||
title: "Cape Coral Burrowing Owl",
|
||||
location: "Cape Coral, FL",
|
||||
fact: "The burrowing owl is the official city bird of Cape Coral. These unique owls nest underground and are active during the day."
|
||||
};
|
||||
case "2":
|
||||
return {
|
||||
title: "Burrowing Owl Habitat",
|
||||
location: "Cape Coral, FL",
|
||||
fact: "Burrowing owls prefer open areas with low vegetation and create underground burrows that provide shelter for many wildlife species."
|
||||
};
|
||||
case "3":
|
||||
return {
|
||||
title: "Owl Burrow Monitoring",
|
||||
location: "Cape Coral, FL",
|
||||
fact: "CCFW volunteers maintain over 2,500 burrows throughout Cape Coral to protect these threatened ground-dwelling owls."
|
||||
};
|
||||
default:
|
||||
return {
|
||||
title: `Burrowing Owl Cam ${id}`,
|
||||
location: "Cape Coral, FL",
|
||||
fact: "Burrowing owls are Florida's smallest owl species and are known for their distinctive long legs and daytime activity."
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
// Client-side component for dynamic time to avoid hydration errors
|
||||
const ClientTimeDisplay: React.FC = () => {
|
||||
const [currentTime, setCurrentTime] = React.useState<string>('');
|
||||
|
||||
React.useEffect(() => {
|
||||
setCurrentTime(new Date().toLocaleDateString() + ' • ' + new Date().toLocaleTimeString());
|
||||
}, []);
|
||||
|
||||
return <span className="bg-ccfw-beige/50 py-1 px-2 rounded">{currentTime}</span>;
|
||||
};
|
||||
|
||||
const LiveStream: React.FC<LiveStreamProps> = ({ id }) => {
|
||||
// This would be determined by your backend in a real app
|
||||
const isLive = id !== "3"; // Let's assume stream #3 is offline for testing
|
||||
|
||||
const streamInfo = getStreamInfo(id);
|
||||
// Use a fixed viewer count to avoid hydration errors
|
||||
const viewerCount = isLive ? (id === "1" ? 128 : id === "2" ? 86 : 75) : 0;
|
||||
|
||||
return (
|
||||
<Card className="border-ccfw-teal/30 bg-gradient-to-b from-ccfw-beige/20 to-ccfw-beige/5 backdrop-blur-sm">
|
||||
<CardHeader className="pb-2 border-b border-ccfw-teal/20">
|
||||
<div className="flex justify-between items-center">
|
||||
<CardTitle className="text-ccfw-teal">{streamInfo.title}</CardTitle>
|
||||
<div className="flex items-center gap-2">
|
||||
<div className={`h-3 w-3 rounded-full ${isLive ? 'bg-ccfw-coral animate-pulse' : 'bg-gray-500'}`}></div>
|
||||
<span className="text-sm font-medium text-ccfw-maroon font-semibold">{isLive ? 'LIVE' : 'OFFLINE'}</span>
|
||||
</div>
|
||||
</div>
|
||||
</CardHeader>
|
||||
<CardContent className="pt-4">
|
||||
<div className="bg-black aspect-video flex flex-col items-center justify-center rounded-md border border-ccfw-teal/30 relative overflow-hidden">
|
||||
{isLive ? (
|
||||
<>
|
||||
<div className="absolute inset-0 bg-gradient-to-b from-ccfw-teal/5 to-transparent"></div>
|
||||
|
||||
{/* Overlay for wildlife stream info */}
|
||||
<div className="absolute top-0 left-0 w-full bg-black/50 p-2 flex justify-between items-center">
|
||||
<div className="flex items-center">
|
||||
<div className="h-2 w-2 rounded-full bg-ccfw-coral animate-pulse mr-2"></div>
|
||||
<span className="text-xs text-white">CCFW Wildlife Stream</span>
|
||||
</div>
|
||||
<div className="text-xs text-white bg-ccfw-teal/80 px-2 py-1 rounded">
|
||||
HD
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="z-10 flex flex-col items-center">
|
||||
<div className="bg-black/60 px-4 py-2 rounded-lg border border-ccfw-teal/30">
|
||||
<p className="text-white font-medium">{streamInfo.location} • Cape Coral Friends of Wildlife</p>
|
||||
<p className="text-xs text-white mt-2">HD Video • Live from Florida</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="absolute bottom-4 right-4 bg-black/70 text-white text-xs px-2 py-1 rounded flex items-center">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" className="h-3 w-3 mr-1 text-ccfw-coral" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
||||
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M15 12a3 3 0 11-6 0 3 3 0 016 0z" />
|
||||
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M2.458 12C3.732 7.943 7.523 5 12 5c4.478 0 8.268 2.943 9.542 7-1.274 4.057-5.064 7-9.542 7-4.477 0-8.268-2.943-9.542-7z" />
|
||||
</svg>
|
||||
{viewerCount}
|
||||
</div>
|
||||
|
||||
{/* Stream controls overlay */}
|
||||
<div className="absolute bottom-0 left-0 w-full bg-gradient-to-t from-black to-transparent pt-8 pb-2 px-4">
|
||||
<div className="flex justify-between items-center">
|
||||
<div className="flex space-x-3">
|
||||
<button className="text-white hover:text-ccfw-coral transition-colors">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" className="h-5 w-5" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
||||
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={1.5} d="M15.536 8.464a5 5 0 010 7.072m2.828-9.9a9 9 0 010 12.728M5.586 15.536a5 5 0 001.414-7.071m-2.829 9.9a9 9 0 010-12.728" />
|
||||
</svg>
|
||||
</button>
|
||||
<button className="text-white hover:text-ccfw-coral transition-colors">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" className="h-5 w-5" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
||||
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={1.5} d="M5 3v4M3 5h4M6 17v4m-2-2h4m5-16l2.286 6.857L21 12l-5.714 2.143L13 21l-2.286-6.857L5 12l5.714-2.143L13 3z" />
|
||||
</svg>
|
||||
</button>
|
||||
</div>
|
||||
<div className="text-xs text-white">
|
||||
Powered by CCFW
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</>
|
||||
) : (
|
||||
<div className="flex flex-col items-center">
|
||||
<div className="bg-black/60 p-4 rounded-lg border border-ccfw-teal/30">
|
||||
<div className="flex items-center mb-3">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" className="h-10 w-10 text-gray-600 mr-3" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
||||
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={1.5} d="M14.752 11.168l-3.197-2.132A1 1 0 0010 9.87v4.263a1 1 0 001.555.832l3.197-2.132a1 1 0 000-1.664z" />
|
||||
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={1.5} d="M21 12a9 9 0 11-18 0 9 9 0 0118 0z" />
|
||||
</svg>
|
||||
<div>
|
||||
<p className="text-white font-medium">Stream currently offline</p>
|
||||
<p className="text-xs text-white/80">Will return soon. Check back later.</p>
|
||||
</div>
|
||||
</div>
|
||||
<div className="text-xs text-white text-center">
|
||||
<a
|
||||
href="https://ccfriendsofwildlife.org/events-and-programs/"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
className="hover:text-ccfw-coral transition-colors"
|
||||
>
|
||||
View upcoming livestream schedule
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
<div className="mt-4 flex justify-between items-center">
|
||||
<div className="text-xs text-ccfw-maroon/70">
|
||||
<ClientTimeDisplay />
|
||||
</div>
|
||||
<div className="flex gap-3">
|
||||
<button className="text-ccfw-teal hover:text-ccfw-coral transition-colors">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" className="h-5 w-5" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
||||
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={1.5} d="M8.684 13.342C8.886 12.938 9 12.482 9 12c0-.482-.114-.938-.316-1.342m0 2.684a3 3 0 110-2.684m0 2.684l6.632 3.316m-6.632-6l6.632-3.316m0 0a3 3 0 105.367-2.684 3 3 0 00-5.367 2.684zm0 9.316a3 3 0 105.368 2.684 3 3 0 00-5.368-2.684z" />
|
||||
</svg>
|
||||
</button>
|
||||
<button className="text-ccfw-teal hover:text-ccfw-coral transition-colors">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" className="h-5 w-5" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
||||
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={1.5} d="M4.318 6.318a4.5 4.5 0 000 6.364L12 20.364l7.682-7.682a4.5 4.5 0 00-6.364-6.364L12 7.636l-1.318-1.318a4.5 4.5 0 00-6.364 0z" />
|
||||
</svg>
|
||||
</button>
|
||||
<a
|
||||
href="https://ccfriendsofwildlife.org/events-and-programs/"
|
||||
target="_blank"
|
||||
className="text-ccfw-teal hover:text-ccfw-coral transition-colors"
|
||||
>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" className="h-5 w-5" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
||||
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={1.5} d="M13 16h-1v-4h-1m1-4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z" />
|
||||
</svg>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Wildlife fact */}
|
||||
<div className="mt-3 bg-ccfw-beige/10 p-3 rounded-md border border-ccfw-teal/20">
|
||||
<div className="flex items-start gap-2">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" className="h-5 w-5 text-ccfw-gold flex-shrink-0 mt-0.5" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
||||
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M13 16h-1v-4h-1m1-4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z" />
|
||||
</svg>
|
||||
<p className="text-sm text-ccfw-maroon font-medium leading-relaxed">
|
||||
<span className="font-semibold text-ccfw-teal">Wildlife Fact:</span> {streamInfo.fact}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</CardContent>
|
||||
</Card>
|
||||
);
|
||||
};
|
||||
|
||||
export default LiveStream;
|
||||
117
app/components/Navbar.tsx
Normal file
117
app/components/Navbar.tsx
Normal file
@ -0,0 +1,117 @@
|
||||
'use client';
|
||||
import React, { useState, useEffect } from 'react';
|
||||
import Link from 'next/link';
|
||||
import { usePathname } from 'next/navigation';
|
||||
import { Menu, X, Eye, Tv2, TreePine, Heart, Calendar, Info } from 'lucide-react';
|
||||
|
||||
const links = [
|
||||
{ href: '/streams', label: 'Live Cams', icon: Tv2 },
|
||||
{ href: '/wildlife', label: 'Wildlife', icon: TreePine },
|
||||
{ href: '/events', label: 'Events', icon: Calendar },
|
||||
{ href: '/donate', label: 'Donate', icon: Heart },
|
||||
{ href: '/about', label: 'About', icon: Info },
|
||||
];
|
||||
|
||||
export default function Navbar() {
|
||||
const [open, setOpen] = useState(false);
|
||||
const [scrolled, setScrolled] = useState(false);
|
||||
const pathname = usePathname();
|
||||
|
||||
useEffect(() => {
|
||||
const handler = () => setScrolled(window.scrollY > 40);
|
||||
window.addEventListener('scroll', handler);
|
||||
return () => window.removeEventListener('scroll', handler);
|
||||
}, []);
|
||||
|
||||
return (
|
||||
<header
|
||||
className={`sticky top-0 z-50 w-full transition-all duration-300 ${
|
||||
scrolled
|
||||
? 'bg-deepGreen/95 backdrop-blur-md shadow-lg shadow-black/30 border-b border-white/5'
|
||||
: 'bg-deepGreen border-b border-white/5'
|
||||
}`}
|
||||
>
|
||||
<div className="max-w-7xl mx-auto px-4 sm:px-6 h-16 flex items-center justify-between gap-6">
|
||||
{/* Logo */}
|
||||
<Link href="/" className="flex items-center gap-2 shrink-0 group">
|
||||
<div className="w-9 h-9 rounded-full bg-teal/20 flex items-center justify-center border border-teal/30 group-hover:border-teal/60 transition-all">
|
||||
<Eye size={20} className="text-teal" />
|
||||
</div>
|
||||
<div className="flex flex-col leading-none">
|
||||
<span className="text-gold font-bold text-base tracking-tight">Owl Stream</span>
|
||||
<span className="text-stone-400 text-[10px] font-medium tracking-widest uppercase">CCFW</span>
|
||||
</div>
|
||||
</Link>
|
||||
|
||||
{/* Desktop Nav */}
|
||||
<nav className="hidden md:flex items-center gap-1">
|
||||
{links.map(({ href, label }) => {
|
||||
const active = pathname === href || pathname.startsWith(href + '/');
|
||||
return (
|
||||
<Link
|
||||
key={href}
|
||||
href={href}
|
||||
className={`px-4 py-2 rounded-lg text-sm font-semibold transition-all ${
|
||||
active
|
||||
? 'bg-teal/20 text-teal'
|
||||
: 'text-stone-300 hover:text-white hover:bg-white/5'
|
||||
}`}
|
||||
>
|
||||
{label}
|
||||
</Link>
|
||||
);
|
||||
})}
|
||||
</nav>
|
||||
|
||||
{/* Donate CTA (desktop) */}
|
||||
<Link
|
||||
href="/donate"
|
||||
className="hidden md:inline-flex items-center gap-2 px-5 py-2 rounded-full bg-gold text-deepGreen font-bold text-sm hover:bg-goldLight transition-all shadow-lg shadow-gold/20 shrink-0"
|
||||
>
|
||||
<Heart size={14} />
|
||||
Support CCFW
|
||||
</Link>
|
||||
|
||||
{/* Mobile hamburger */}
|
||||
<button
|
||||
className="md:hidden p-2 rounded-lg text-stone-300 hover:bg-white/10 transition-all"
|
||||
onClick={() => setOpen(!open)}
|
||||
aria-label="Toggle menu"
|
||||
>
|
||||
{open ? <X size={24} /> : <Menu size={24} />}
|
||||
</button>
|
||||
</div>
|
||||
|
||||
{/* Mobile Menu */}
|
||||
{open && (
|
||||
<div className="md:hidden bg-surfaceGreen border-t border-white/5 px-4 py-4 space-y-1">
|
||||
{links.map(({ href, label, icon: Icon }) => {
|
||||
const active = pathname === href;
|
||||
return (
|
||||
<Link
|
||||
key={href}
|
||||
href={href}
|
||||
onClick={() => setOpen(false)}
|
||||
className={`flex items-center gap-3 px-4 py-3 rounded-xl text-sm font-semibold transition-all ${
|
||||
active ? 'bg-teal/20 text-teal' : 'text-stone-300 hover:bg-white/5 hover:text-white'
|
||||
}`}
|
||||
>
|
||||
<Icon size={18} />
|
||||
{label}
|
||||
</Link>
|
||||
);
|
||||
})}
|
||||
<div className="pt-3 border-t border-white/5">
|
||||
<Link
|
||||
href="/donate"
|
||||
onClick={() => setOpen(false)}
|
||||
className="flex items-center justify-center gap-2 w-full py-3 rounded-xl bg-gold text-deepGreen font-bold text-sm"
|
||||
>
|
||||
<Heart size={16} /> Support CCFW
|
||||
</Link>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
</header>
|
||||
);
|
||||
}
|
||||
@ -1,182 +0,0 @@
|
||||
"use client";
|
||||
|
||||
import React, { useState } from 'react';
|
||||
import { Card, CardContent, CardHeader, CardTitle, CardDescription } from "@/components/ui/card";
|
||||
import { Button } from "@/components/ui/button";
|
||||
|
||||
interface OwlInfoProps {
|
||||
id: string;
|
||||
}
|
||||
|
||||
const OwlInfo: React.FC<OwlInfoProps> = ({ id }) => {
|
||||
const [activeTab, setActiveTab] = useState<'facts' | 'habitat' | 'conservation'>('facts');
|
||||
|
||||
// Get burrowing owl data based on stream ID
|
||||
const getWildlifeData = () => {
|
||||
switch (id) {
|
||||
case "1":
|
||||
return {
|
||||
species: "Burrowing Owl",
|
||||
scientificName: "Athene cunicularia",
|
||||
location: "Cape Coral, FL",
|
||||
facts: [
|
||||
"Burrowing owls are small, long-legged owls that nest underground in burrows",
|
||||
"Unlike most owls, they are active during the day (diurnal)",
|
||||
"They stand about 9 inches tall and have bright yellow eyes",
|
||||
"The City of Cape Coral has designated the burrowing owl as its official city bird"
|
||||
],
|
||||
habitat: "Cape Coral has the largest population of burrowing owls in Florida. They prefer open areas with low vegetation such as prairies, grasslands, and open areas of urban development. CCFW volunteers maintain over 2,500 burrows throughout Cape Coral.",
|
||||
conservation: "Burrowing owls are listed as a state-threatened species in Florida. Development of their habitats is the biggest threat to their survival. CCFW works to protect and maintain burrows, educate the public, and collaborate with local authorities to ensure these birds have safe places to nest.",
|
||||
ccfwLink: "https://ccfriendsofwildlife.org/burrowing-owls/"
|
||||
};
|
||||
case "2":
|
||||
return {
|
||||
species: "Burrowing Owl",
|
||||
scientificName: "Athene cunicularia",
|
||||
location: "Cape Coral, FL",
|
||||
facts: [
|
||||
"Burrowing owls create underground burrows that can be up to 30 feet long",
|
||||
"They often use burrows created by other animals like prairie dogs or armadillos",
|
||||
"These owls are known for their distinctive 'bobblehead' behavior when curious",
|
||||
"They can live up to 9 years in the wild with proper habitat protection"
|
||||
],
|
||||
habitat: "Burrowing owls prefer open, grassy areas with sparse vegetation. They are commonly found in prairies, agricultural fields, and urban areas with suitable open spaces. The owls dig their own burrows or modify existing ones.",
|
||||
conservation: "Habitat loss from urban development is the primary threat to burrowing owls. CCFW's burrow maintenance program helps protect existing burrows and creates artificial burrows to support the owl population in Cape Coral.",
|
||||
ccfwLink: "https://ccfriendsofwildlife.org/burrowing-owls/"
|
||||
};
|
||||
case "3":
|
||||
return {
|
||||
species: "Burrowing Owl",
|
||||
scientificName: "Athene cunicularia",
|
||||
location: "Cape Coral, FL",
|
||||
facts: [
|
||||
"Burrowing owls are Florida's smallest owl species",
|
||||
"They have long legs adapted for walking and running on the ground",
|
||||
"Their diet consists mainly of insects, small mammals, and reptiles",
|
||||
"They are the only owl species that nests exclusively underground"
|
||||
],
|
||||
habitat: "These unique owls inhabit open grasslands, pastures, and urban areas with low vegetation. They are particularly well-adapted to the Florida landscape and have thrived in areas where other wildlife has declined.",
|
||||
conservation: "CCFW volunteers monitor and maintain over 2,500 burrows in Cape Coral. The organization's educational programs help the community understand the importance of protecting these threatened birds and their habitats.",
|
||||
ccfwLink: "https://ccfriendsofwildlife.org/burrowing-owls/"
|
||||
};
|
||||
default:
|
||||
return {
|
||||
species: "Burrowing Owl",
|
||||
scientificName: "Athene cunicularia",
|
||||
location: "Cape Coral, FL",
|
||||
facts: [
|
||||
"Burrowing owls are the official city bird of Cape Coral",
|
||||
"They are diurnal, meaning they are active during the day",
|
||||
"These owls have distinctive long legs and bright yellow eyes",
|
||||
"CCFW maintains over 2,500 burrows to protect this threatened species"
|
||||
],
|
||||
habitat: "Cape Coral provides ideal habitat for burrowing owls with its mix of urban development and open spaces. The city has the largest population of burrowing owls in Florida due to successful conservation efforts.",
|
||||
conservation: "Cape Coral Friends of Wildlife works tirelessly to protect burrowing owls through habitat preservation, burrow maintenance, public education, and collaboration with local authorities.",
|
||||
ccfwLink: "https://ccfriendsofwildlife.org/burrowing-owls/"
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
const wildlifeData = getWildlifeData();
|
||||
|
||||
return (
|
||||
<Card className="border-ccfw-teal/30 bg-gradient-to-b from-ccfw-beige/20 to-ccfw-beige/5 backdrop-blur-sm">
|
||||
<CardHeader className="border-b border-ccfw-teal/20 bg-ccfw-beige/10">
|
||||
<CardTitle className="text-ccfw-teal">About {wildlifeData.species}</CardTitle>
|
||||
<CardDescription className="text-ccfw-maroon font-medium italic">
|
||||
{wildlifeData.scientificName && (
|
||||
<>{wildlifeData.scientificName} • </>
|
||||
)}
|
||||
{wildlifeData.location}
|
||||
</CardDescription>
|
||||
</CardHeader>
|
||||
<CardContent className="space-y-4 pt-4">
|
||||
<div className="flex space-x-1 bg-ccfw-beige/10 p-1 rounded-md">
|
||||
<Button
|
||||
variant="ghost"
|
||||
className={`flex-1 text-xs h-8 ${activeTab === 'facts' ? 'bg-ccfw-teal/20 text-ccfw-teal' : 'text-ccfw-maroon hover:text-ccfw-teal hover:bg-ccfw-teal/10'}`}
|
||||
onClick={() => setActiveTab('facts')}
|
||||
>
|
||||
Facts
|
||||
</Button>
|
||||
<Button
|
||||
variant="ghost"
|
||||
className={`flex-1 text-xs h-8 ${activeTab === 'habitat' ? 'bg-ccfw-teal/20 text-ccfw-teal' : 'text-ccfw-maroon hover:text-ccfw-teal hover:bg-ccfw-teal/10'}`}
|
||||
onClick={() => setActiveTab('habitat')}
|
||||
>
|
||||
Habitat
|
||||
</Button>
|
||||
<Button
|
||||
variant="ghost"
|
||||
className={`flex-1 text-xs h-8 ${activeTab === 'conservation' ? 'bg-ccfw-teal/20 text-ccfw-teal' : 'text-ccfw-maroon hover:text-ccfw-teal hover:bg-ccfw-teal/10'}`}
|
||||
onClick={() => setActiveTab('conservation')}
|
||||
>
|
||||
Conservation
|
||||
</Button>
|
||||
</div>
|
||||
|
||||
<div className="min-h-[180px]">
|
||||
{activeTab === 'facts' && (
|
||||
<div className="space-y-2">
|
||||
<ul className="list-disc list-inside space-y-2 text-sm text-ccfw-maroon font-medium">
|
||||
{wildlifeData.facts.map((fact, index) => (
|
||||
<li key={index}>{fact}</li>
|
||||
))}
|
||||
</ul>
|
||||
</div>
|
||||
)}
|
||||
|
||||
{activeTab === 'habitat' && (
|
||||
<div className="space-y-2">
|
||||
<p className="text-sm text-ccfw-maroon font-medium">{wildlifeData.habitat}</p>
|
||||
</div>
|
||||
)}
|
||||
|
||||
{activeTab === 'conservation' && (
|
||||
<div className="space-y-3">
|
||||
<p className="text-sm text-ccfw-maroon font-medium">{wildlifeData.conservation}</p>
|
||||
|
||||
<div className="bg-ccfw-beige/10 p-3 rounded-md border border-ccfw-teal/20 flex flex-col sm:flex-row items-center gap-3">
|
||||
<div className="bg-ccfw-gold/20 p-2 rounded-full">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" className="h-6 w-6 text-ccfw-gold" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
||||
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={1.5} d="M16 7a4 4 0 11-8 0 4 4 0 018 0zM12 14a7 7 0 00-7 7h14a7 7 0 00-7-7z" />
|
||||
</svg>
|
||||
</div>
|
||||
<div className="text-center sm:text-left">
|
||||
<p className="text-sm text-ccfw-maroon font-medium">
|
||||
<span className="font-medium text-ccfw-teal">How you can help:</span> Join the Cape Coral Friends of Wildlife in their mission to preserve and protect these incredible creatures.
|
||||
</p>
|
||||
<a
|
||||
href="https://ccfriendsofwildlife.org/volunteer/"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
className="text-xs text-ccfw-teal hover:text-ccfw-coral transition-colors"
|
||||
>
|
||||
Learn about volunteer opportunities
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
|
||||
<div className="pt-3 border-t border-ccfw-teal/20 flex justify-between items-center">
|
||||
<span className="text-xs text-ccfw-maroon font-medium">Updated daily</span>
|
||||
<a
|
||||
href={wildlifeData.ccfwLink}
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
className="text-ccfw-teal text-xs hover:text-ccfw-coral transition-colors flex items-center gap-1"
|
||||
>
|
||||
Learn More
|
||||
<svg xmlns="http://www.w3.org/2000/svg" className="h-4 w-4" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
||||
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={1.5} d="M10 6H6a2 2 0 00-2 2v10a2 2 0 002 2h10a2 2 0 002-2v-4M14 4h6m0 0v6m0-6L10 14" />
|
||||
</svg>
|
||||
</a>
|
||||
</div>
|
||||
</CardContent>
|
||||
</Card>
|
||||
);
|
||||
};
|
||||
|
||||
export default OwlInfo;
|
||||
26
app/components/StatsBar.tsx
Normal file
26
app/components/StatsBar.tsx
Normal file
@ -0,0 +1,26 @@
|
||||
import React from 'react';
|
||||
import { Eye, Home, Clock, Tv2 } from 'lucide-react';
|
||||
import type { Stat } from '@/lib/api';
|
||||
|
||||
const items = [
|
||||
{ key: 'owlCount', label: 'Owls Tracked', icon: Eye, unit: '' },
|
||||
{ key: 'burrowCount', label: 'Active Burrows', icon: Home, unit: '' },
|
||||
{ key: 'volunteerHours', label: 'Volunteer Hours', icon: Clock, unit: 'hrs' },
|
||||
{ key: 'activeStreams', label: 'Live Cams', icon: Tv2, unit: '' },
|
||||
] as const;
|
||||
|
||||
export default function StatsBar({ stats }: { stats: Stat }) {
|
||||
return (
|
||||
<div className="grid grid-cols-2 lg:grid-cols-4 gap-px bg-white/5 rounded-2xl overflow-hidden border border-white/5">
|
||||
{items.map(({ key, label, icon: Icon, unit }) => (
|
||||
<div key={key} className="bg-surfaceGreen px-6 py-7 flex flex-col items-center text-center gap-2">
|
||||
<Icon size={22} className="text-teal opacity-80" />
|
||||
<div className="text-3xl font-black text-gold tabular-nums">
|
||||
{stats[key].toLocaleString()}{unit}
|
||||
</div>
|
||||
<div className="text-xs font-semibold text-stone-400 uppercase tracking-widest">{label}</div>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
62
app/components/StreamCard.tsx
Normal file
62
app/components/StreamCard.tsx
Normal file
@ -0,0 +1,62 @@
|
||||
import React from 'react';
|
||||
import Link from 'next/link';
|
||||
import { Radio, Users, MapPin } from 'lucide-react';
|
||||
import type { Stream } from '@/lib/api';
|
||||
|
||||
export default function StreamCard({ stream }: { stream: Stream }) {
|
||||
return (
|
||||
<Link href={`/streams/${stream.id}`} className="group block">
|
||||
<div className="bg-surfaceGreen border border-white/5 rounded-2xl overflow-hidden hover:border-teal/30 transition-all hover:shadow-xl hover:shadow-teal/5">
|
||||
{/* Thumbnail area */}
|
||||
<div className="relative aspect-video bg-black/40 overflow-hidden">
|
||||
{stream.thumbnailUrl ? (
|
||||
// eslint-disable-next-line @next/next/no-img-element
|
||||
<img
|
||||
src={stream.thumbnailUrl}
|
||||
alt={stream.name}
|
||||
className="w-full h-full object-cover group-hover:scale-105 transition-transform duration-500"
|
||||
/>
|
||||
) : (
|
||||
<div className="w-full h-full flex items-center justify-center">
|
||||
<Radio size={48} className="text-stone-600" />
|
||||
</div>
|
||||
)}
|
||||
|
||||
{/* Status badge */}
|
||||
<div className={`absolute top-3 left-3 flex items-center gap-1.5 px-3 py-1 rounded-full text-xs font-bold uppercase tracking-wider ${
|
||||
stream.status === 'live'
|
||||
? 'bg-red-500/90 text-white'
|
||||
: 'bg-black/60 text-stone-300'
|
||||
}`}>
|
||||
{stream.status === 'live' && <span className="w-1.5 h-1.5 rounded-full bg-white animate-pulse" />}
|
||||
{stream.status === 'live' ? 'Live' : 'Offline'}
|
||||
</div>
|
||||
|
||||
{/* Viewer count */}
|
||||
{stream.viewerCount > 0 && (
|
||||
<div className="absolute top-3 right-3 flex items-center gap-1 bg-black/60 px-2 py-1 rounded-full text-xs text-stone-200 font-semibold">
|
||||
<Users size={12} />
|
||||
{stream.viewerCount.toLocaleString()}
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
|
||||
{/* Info */}
|
||||
<div className="p-5 space-y-2">
|
||||
<h3 className="font-bold text-white group-hover:text-teal transition-colors text-base leading-snug">
|
||||
{stream.name}
|
||||
</h3>
|
||||
{stream.location && (
|
||||
<div className="flex items-center gap-1.5 text-xs text-stone-400 font-medium">
|
||||
<MapPin size={12} />
|
||||
{stream.location}
|
||||
</div>
|
||||
)}
|
||||
{stream.description && (
|
||||
<p className="text-sm text-stone-400 line-clamp-2 leading-relaxed">{stream.description}</p>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
</Link>
|
||||
);
|
||||
}
|
||||
48
app/components/WildlifeCard.tsx
Normal file
48
app/components/WildlifeCard.tsx
Normal file
@ -0,0 +1,48 @@
|
||||
import React from 'react';
|
||||
import { Shield } from 'lucide-react';
|
||||
import type { Wildlife } from '@/lib/api';
|
||||
|
||||
const statusColor: Record<string, string> = {
|
||||
'Threatened': 'bg-red-500/20 text-red-400 border-red-500/30',
|
||||
'Protected': 'bg-amber-500/20 text-amber-400 border-amber-500/30',
|
||||
'Least Concern': 'bg-emerald-500/20 text-emerald-400 border-emerald-500/30',
|
||||
'Endangered': 'bg-red-700/30 text-red-300 border-red-600/30',
|
||||
};
|
||||
|
||||
export default function WildlifeCard({ species }: { species: Wildlife }) {
|
||||
const colors = statusColor[species.status] ?? 'bg-stone-500/20 text-stone-400 border-stone-500/30';
|
||||
return (
|
||||
<div className="bg-surfaceGreen border border-white/5 rounded-2xl overflow-hidden hover:border-gold/20 transition-all group">
|
||||
{/* Image */}
|
||||
<div className="aspect-[4/3] bg-black/40 overflow-hidden">
|
||||
{species.imageUrl ? (
|
||||
// eslint-disable-next-line @next/next/no-img-element
|
||||
<img
|
||||
src={species.imageUrl}
|
||||
alt={species.name}
|
||||
className="w-full h-full object-cover group-hover:scale-105 transition-transform duration-500"
|
||||
/>
|
||||
) : (
|
||||
<div className="w-full h-full flex items-center justify-center text-6xl">🦉</div>
|
||||
)}
|
||||
</div>
|
||||
<div className="p-5 space-y-3">
|
||||
{/* Status */}
|
||||
<span className={`inline-flex items-center gap-1.5 px-3 py-1 rounded-full text-[10px] font-bold uppercase tracking-wider border ${colors}`}>
|
||||
<Shield size={10} />
|
||||
{species.status}
|
||||
</span>
|
||||
<div>
|
||||
<h3 className="font-bold text-white text-lg leading-tight">{species.name}</h3>
|
||||
<p className="text-xs text-stone-500 italic mt-0.5">{species.scientificName}</p>
|
||||
</div>
|
||||
<p className="text-sm text-stone-400 leading-relaxed line-clamp-3">{species.description}</p>
|
||||
<div className="pt-2 border-t border-white/5">
|
||||
<p className="text-xs text-stone-500 font-medium">
|
||||
<span className="text-stone-400">Habitat: </span>{species.habitat}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
81
app/donate/page.tsx
Normal file
81
app/donate/page.tsx
Normal file
@ -0,0 +1,81 @@
|
||||
import React from 'react';
|
||||
import { Heart, Shield, Camera, TreePine } from 'lucide-react';
|
||||
import { api, Campaign } from '@/lib/api';
|
||||
import DonationCard from '../components/DonationCard';
|
||||
|
||||
const FALLBACK_CAMPAIGNS: Campaign[] = [
|
||||
{
|
||||
id: '1', title: 'Land Preservation Fund',
|
||||
description: 'Help CCFW acquire and protect critical burrowing owl habitat before developers can build on it.',
|
||||
goal: 50000, raised: 31250,
|
||||
},
|
||||
{
|
||||
id: '2', title: 'Volunteer Equipment',
|
||||
description: 'Fund field monitors, spotting scopes, GPS units, and protective gear for our volunteer teams.',
|
||||
goal: 15000, raised: 9800,
|
||||
},
|
||||
{
|
||||
id: '3', title: 'Camera Infrastructure',
|
||||
description: 'Expand our network of wildlife cameras. Each camera streams 24/7 and reaches thousands of viewers.',
|
||||
goal: 25000, raised: 14200,
|
||||
},
|
||||
];
|
||||
|
||||
const icons = [TreePine, Shield, Camera];
|
||||
|
||||
async function getCampaigns(): Promise<Campaign[]> {
|
||||
try { return await api.getCampaigns(); }
|
||||
catch { return FALLBACK_CAMPAIGNS; }
|
||||
}
|
||||
|
||||
export default async function DonatePage() {
|
||||
const campaigns = await getCampaigns();
|
||||
|
||||
return (
|
||||
<div className="max-w-7xl mx-auto px-6 py-16 space-y-16">
|
||||
<header className="max-w-3xl space-y-4">
|
||||
<div className="flex items-center gap-2 text-gold text-sm font-bold uppercase tracking-widest">
|
||||
<Heart size={16} /> Support Conservation
|
||||
</div>
|
||||
<h1 className="text-4xl font-black text-white">Help Protect Cape Coral Wildlife</h1>
|
||||
<p className="text-stone-400 text-lg leading-relaxed">
|
||||
Every dollar goes directly to protecting burrowing owls, gopher tortoises, and native Florida wildlife. CCFW is a 501(c)(3) nonprofit — your donation is tax deductible.
|
||||
</p>
|
||||
</header>
|
||||
|
||||
{/* Impact banner */}
|
||||
<div className="grid grid-cols-1 md:grid-cols-3 gap-px bg-white/5 rounded-2xl overflow-hidden">
|
||||
{[
|
||||
{ icon: icons[0], title: 'Land Preserved', value: '150+ acres' },
|
||||
{ icon: icons[1], title: 'Burrows Monitored', value: '2,000+' },
|
||||
{ icon: icons[2], title: 'Live Cameras', value: '12 active' },
|
||||
].map(({ icon: Icon, title, value }) => (
|
||||
<div key={title} className="bg-surfaceGreen p-8 flex flex-col items-center text-center gap-3">
|
||||
<Icon size={28} className="text-teal" />
|
||||
<div className="text-2xl font-black text-gold">{value}</div>
|
||||
<div className="text-xs text-stone-400 font-semibold uppercase tracking-wider">{title}</div>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
|
||||
{/* Campaign cards */}
|
||||
<div className="space-y-6">
|
||||
<h2 className="text-2xl font-black text-white">Active Campaigns</h2>
|
||||
<div className="grid grid-cols-1 md:grid-cols-3 gap-6">
|
||||
{campaigns.map((c) => <DonationCard key={c.id} campaign={c} />)}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Trust signals */}
|
||||
<div className="bg-surfaceGreen border border-white/5 rounded-2xl p-8 flex flex-col md:flex-row items-center gap-8">
|
||||
<Shield size={48} className="text-teal shrink-0" />
|
||||
<div>
|
||||
<h3 className="font-bold text-white text-xl mb-2">Secure & Tax-Deductible</h3>
|
||||
<p className="text-stone-400 text-sm leading-relaxed max-w-2xl">
|
||||
Cape Coral Friends of Wildlife is a registered 501(c)(3) nonprofit organization. All donations are tax-deductible to the fullest extent permitted by law. We never sell your information. Payment processing powered by Stripe.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
69
app/events/page.tsx
Normal file
69
app/events/page.tsx
Normal file
@ -0,0 +1,69 @@
|
||||
import React from 'react';
|
||||
import { Calendar } from 'lucide-react';
|
||||
import { api, Event } from '@/lib/api';
|
||||
import EventCard from '../components/EventCard';
|
||||
|
||||
const FALLBACK_EVENTS: Event[] = [
|
||||
{
|
||||
id: '1',
|
||||
title: 'Burrowing Owl Survey Walk',
|
||||
date: new Date(Date.now() + 3 * 24 * 60 * 60 * 1000).toISOString(),
|
||||
location: 'Rotary Park, Cape Coral',
|
||||
description: 'Join CCFW volunteers for our monthly owl survey. Learn to identify burrows and record sighting data. All skill levels welcome.',
|
||||
rsvpCount: 14,
|
||||
capacity: 25,
|
||||
},
|
||||
{
|
||||
id: '2',
|
||||
title: 'Habitat Restoration Day',
|
||||
date: new Date(Date.now() + 10 * 24 * 60 * 60 * 1000).toISOString(),
|
||||
location: 'Four Mile Cove, Cape Coral',
|
||||
description: 'Help us plant native vegetation to restore burrowing owl habitat. Gloves and tools provided. Bring water and sunscreen.',
|
||||
rsvpCount: 8,
|
||||
capacity: 20,
|
||||
},
|
||||
{
|
||||
id: '3',
|
||||
title: 'Community Wildlife Photography Workshop',
|
||||
date: new Date(Date.now() + 17 * 24 * 60 * 60 * 1000).toISOString(),
|
||||
location: 'CCFW Conservation Center',
|
||||
description: 'Professional wildlife photographer workshop covering camera settings, ethics of wildlife photography, and best spots in Cape Coral.',
|
||||
rsvpCount: 22,
|
||||
capacity: 30,
|
||||
},
|
||||
];
|
||||
|
||||
async function getEvents(): Promise<Event[]> {
|
||||
try { return await api.getEvents(); }
|
||||
catch { return FALLBACK_EVENTS; }
|
||||
}
|
||||
|
||||
export default async function EventsPage() {
|
||||
const events = await getEvents();
|
||||
|
||||
return (
|
||||
<div className="max-w-5xl mx-auto px-6 py-16 space-y-14">
|
||||
<header className="space-y-4">
|
||||
<div className="flex items-center gap-2 text-teal text-sm font-bold uppercase tracking-widest">
|
||||
<Calendar size={16} /> Upcoming
|
||||
</div>
|
||||
<h1 className="text-4xl font-black text-white">CCFW Events</h1>
|
||||
<p className="text-stone-400 text-lg max-w-2xl leading-relaxed">
|
||||
Get involved! CCFW hosts regular surveys, restoration days, and educational events for the Cape Coral community.
|
||||
</p>
|
||||
</header>
|
||||
|
||||
<div className="space-y-5">
|
||||
{events.length === 0 ? (
|
||||
<div className="flex flex-col items-center py-24 gap-4 text-stone-500">
|
||||
<Calendar size={48} className="text-stone-600" />
|
||||
<p className="text-lg font-semibold">No upcoming events</p>
|
||||
<p className="text-sm">Check back soon or follow us on social media.</p>
|
||||
</div>
|
||||
) : (
|
||||
events.map((e) => <EventCard key={e.id} event={e} />)
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@ -3,54 +3,29 @@
|
||||
@tailwind utilities;
|
||||
|
||||
:root {
|
||||
/* CCFW Colors */
|
||||
--background: 25 25 25;
|
||||
--foreground: 230 230 230;
|
||||
--muted: 50 50 50;
|
||||
--muted-foreground: 180 180 180;
|
||||
|
||||
/* Teal/turquoise from CCFW site */
|
||||
--accent: 0 130 167;
|
||||
--accent-foreground: 255 255 255;
|
||||
|
||||
/* CCFW Colors */
|
||||
--card: 233 230 223;
|
||||
--card-foreground: 51 51 51;
|
||||
|
||||
/* Teal/turquoise from CCFW */
|
||||
--primary: 0 130 167;
|
||||
--primary-foreground: 255 255 255;
|
||||
|
||||
/* CCFW Yellow/Gold */
|
||||
--secondary: 246 202 66;
|
||||
--secondary-foreground: 51 51 51;
|
||||
|
||||
/* Coral red from CCFW site */
|
||||
--destructive: 255 133 106;
|
||||
--destructive-foreground: 255 255 255;
|
||||
|
||||
/* CCFW Colors */
|
||||
--border: 204 204 204;
|
||||
--input: 233 230 223;
|
||||
--ring: 0 130 167;
|
||||
|
||||
/* Additional CCFW colors */
|
||||
--ccfw-gold: 246 202 66;
|
||||
--ccfw-teal: 0 130 167;
|
||||
--ccfw-coral: 255 133 106;
|
||||
--ccfw-beige: 233 230 223;
|
||||
--ccfw-maroon: 88 40 67;
|
||||
--deep-green: #0a1f1a;
|
||||
--surface-green: #112920;
|
||||
--gold: #c4a265;
|
||||
--teal: #0082a7;
|
||||
}
|
||||
|
||||
body {
|
||||
color: rgb(var(--foreground));
|
||||
background: rgb(var(--background));
|
||||
html, body {
|
||||
background-color: #0a1f1a;
|
||||
color: #e8e0d0;
|
||||
font-family: system-ui, -apple-system, sans-serif;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
@layer utilities {
|
||||
.neon-glow {
|
||||
text-shadow: 0 0 5px rgb(var(--accent) / 0.5),
|
||||
0 0 10px rgb(var(--accent) / 0.5),
|
||||
0 0 15px rgb(var(--accent) / 0.5);
|
||||
}
|
||||
::-webkit-scrollbar {
|
||||
width: 8px;
|
||||
}
|
||||
::-webkit-scrollbar-track {
|
||||
background: #0a1f1a;
|
||||
}
|
||||
::-webkit-scrollbar-thumb {
|
||||
background: #1e4a3c;
|
||||
border-radius: 4px;
|
||||
}
|
||||
::-webkit-scrollbar-thumb:hover {
|
||||
background: #0082a7;
|
||||
}
|
||||
|
||||
@ -1,19 +1,21 @@
|
||||
import type { Metadata } from "next";
|
||||
import "./globals.css";
|
||||
import type { Metadata } from 'next';
|
||||
import './globals.css';
|
||||
import Navbar from './components/Navbar';
|
||||
import Footer from './components/Footer';
|
||||
|
||||
export const metadata: Metadata = {
|
||||
title: "Cape Coral Burrowing Owl Livestream",
|
||||
description: "Live stream of burrowing owls in Cape Coral",
|
||||
title: 'Owl Stream | Cape Coral Friends of Wildlife',
|
||||
description: 'Live burrowing owl cams, wildlife conservation, and nature in Cape Coral, Florida.',
|
||||
};
|
||||
|
||||
export default function RootLayout({
|
||||
children,
|
||||
}: {
|
||||
children: React.ReactNode
|
||||
}) {
|
||||
export default function RootLayout({ children }: { children: React.ReactNode }) {
|
||||
return (
|
||||
<html lang="en">
|
||||
<body>{children}</body>
|
||||
<body className="bg-deepGreen text-stone-100 min-h-screen flex flex-col">
|
||||
<Navbar />
|
||||
<main className="flex-1">{children}</main>
|
||||
<Footer />
|
||||
</body>
|
||||
</html>
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
@ -1,184 +0,0 @@
|
||||
import React from 'react';
|
||||
import Link from 'next/link';
|
||||
import LiveStream from '@/app/components/LiveStream';
|
||||
import DonationPanel from '@/app/components/DonationPanel';
|
||||
import OwlInfo from '@/app/components/OwlInfo';
|
||||
import { Button } from "@/components/ui/button";
|
||||
import { Card, CardContent } from "@/components/ui/card";
|
||||
|
||||
// This would come from an API or database in a real app
|
||||
const livestreamsData = [
|
||||
{
|
||||
id: "1",
|
||||
name: "Cape Coral Burrowing Owl",
|
||||
location: "Cape Coral, FL",
|
||||
status: "Live",
|
||||
viewers: 128,
|
||||
description: "Watch these unique ground-dwelling owls at their burrows in Cape Coral. These protected birds are the official city bird of Cape Coral!"
|
||||
},
|
||||
{
|
||||
id: "2",
|
||||
name: "Sanibel Island Osprey",
|
||||
location: "Sanibel Island, FL",
|
||||
status: "Live",
|
||||
viewers: 86,
|
||||
description: "Observe ospreys building nests and hunting for fish around Sanibel Island."
|
||||
},
|
||||
{
|
||||
id: "3",
|
||||
name: "Everglades Alligator",
|
||||
location: "Everglades National Park, FL",
|
||||
status: "Offline",
|
||||
viewers: 0,
|
||||
description: "Temporarily offline. Usually shows alligators in their natural habitat in the Everglades."
|
||||
},
|
||||
];
|
||||
|
||||
export default function LivestreamPage({ params }: { params: { id: string } }) {
|
||||
// Find the stream data based on the ID
|
||||
const streamData = livestreamsData.find(stream => stream.id === params.id) || {
|
||||
id: params.id,
|
||||
name: `Wildlife Livestream ${params.id}`,
|
||||
location: "Florida",
|
||||
status: "Live",
|
||||
viewers: Math.floor(Math.random() * 100) + 50,
|
||||
description: "Experience the natural beauty of Florida's wildlife."
|
||||
};
|
||||
|
||||
return (
|
||||
<div className="min-h-screen bg-background text-foreground">
|
||||
<header className="bg-ccfw-beige/90 backdrop-blur-sm sticky top-0 z-10 border-b border-ccfw-teal/20">
|
||||
<div className="max-w-7xl mx-auto py-4 px-4 sm:px-6 lg:px-8 flex justify-between items-center">
|
||||
<div>
|
||||
<Button variant="ghost" className="text-ccfw-teal mb-2" asChild>
|
||||
<Link href="/">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" className="h-5 w-5 mr-1 inline" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
||||
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M15 19l-7-7 7-7" />
|
||||
</svg>
|
||||
Back to all streams
|
||||
</Link>
|
||||
</Button>
|
||||
<h1 className="text-3xl font-bold text-ccfw-teal">{streamData.name}</h1>
|
||||
<p className="text-ccfw-maroon text-sm mt-1">{streamData.location}</p>
|
||||
</div>
|
||||
<div className="flex items-center gap-3">
|
||||
<div className={`h-3 w-3 rounded-full ${streamData.status === 'Live' ? 'bg-ccfw-coral animate-pulse' : 'bg-gray-500'}`}></div>
|
||||
<span className="text-sm font-medium text-ccfw-maroon font-semibold">{streamData.status}</span>
|
||||
</div>
|
||||
</div>
|
||||
</header>
|
||||
<main className="max-w-7xl mx-auto py-6 sm:px-6 lg:px-8">
|
||||
<div className="px-4 py-6 sm:px-0">
|
||||
<div className="grid grid-cols-1 lg:grid-cols-3 gap-6">
|
||||
<div className="lg:col-span-2">
|
||||
<LiveStream id={streamData.id} />
|
||||
|
||||
<div className="mt-6">
|
||||
<Card className="border-ccfw-teal/30 bg-gradient-to-b from-ccfw-beige/20 to-ccfw-beige/5 backdrop-blur-sm">
|
||||
<CardContent className="pt-6">
|
||||
<div className="flex items-start gap-4">
|
||||
<div className="bg-ccfw-teal/10 p-3 rounded-full">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" className="h-6 w-6 text-ccfw-teal" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
||||
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={1.5} d="M13 16h-1v-4h-1m1-4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z" />
|
||||
</svg>
|
||||
</div>
|
||||
<div>
|
||||
<h3 className="text-lg font-medium text-ccfw-teal mb-2">About this livestream</h3>
|
||||
<p className="text-sm text-ccfw-maroon font-medium">
|
||||
This livestream is provided by Cape Coral Friends of Wildlife, a volunteer organization dedicated to the protection and preservation of local wildlife. These cameras help researchers monitor wildlife behavior while allowing the public to connect with nature.
|
||||
</p>
|
||||
<p className="text-sm mt-2">
|
||||
<a
|
||||
href={`https://ccfriendsofwildlife.org/burrowing-owls/`}
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
className="text-ccfw-teal hover:text-ccfw-coral transition-colors underline"
|
||||
>
|
||||
Learn more about our conservation efforts
|
||||
</a>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</CardContent>
|
||||
</Card>
|
||||
</div>
|
||||
</div>
|
||||
<div className="space-y-6">
|
||||
<DonationPanel id={streamData.id} />
|
||||
<OwlInfo id={streamData.id} />
|
||||
|
||||
<Card className="border-ccfw-teal/30 bg-gradient-to-b from-ccfw-beige/20 to-ccfw-beige/5 backdrop-blur-sm overflow-hidden">
|
||||
<CardContent className="pt-6">
|
||||
<h3 className="text-lg font-medium text-ccfw-teal mb-4">Get Involved</h3>
|
||||
<ul className="space-y-3">
|
||||
<li className="flex items-center gap-3">
|
||||
<div className="bg-ccfw-gold/20 p-2 rounded-full">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" className="h-4 w-4 text-ccfw-gold" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
||||
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M21 13.255A23.931 23.931 0 0112 15c-3.183 0-6.22-.62-9-1.745M16 6V4a2 2 0 00-2-2h-4a2 2 0 00-2 2v2m4 6h.01M5 20h14a2 2 0 002-2V8a2 2 0 00-2-2H5a2 2 0 00-2 2v10a2 2 0 002 2z" />
|
||||
</svg>
|
||||
</div>
|
||||
<a
|
||||
href="https://ccfriendsofwildlife.org/volunteer/"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
className="text-sm text-ccfw-maroon font-medium hover:text-ccfw-teal transition-colors"
|
||||
>
|
||||
Volunteer with CCFW
|
||||
</a>
|
||||
</li>
|
||||
<li className="flex items-center gap-3">
|
||||
<div className="bg-ccfw-teal/20 p-2 rounded-full">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" className="h-4 w-4 text-ccfw-teal" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
||||
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M8 7V3m8 4V3m-9 8h10M5 21h14a2 2 0 002-2V7a2 2 0 00-2-2H5a2 2 0 00-2 2v12a2 2 0 002 2z" />
|
||||
</svg>
|
||||
</div>
|
||||
<a
|
||||
href="https://ccfriendsofwildlife.org/events-and-programs/"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
className="text-sm text-ccfw-maroon font-medium hover:text-ccfw-teal transition-colors"
|
||||
>
|
||||
Attend an Event
|
||||
</a>
|
||||
</li>
|
||||
<li className="flex items-center gap-3">
|
||||
<div className="bg-ccfw-coral/20 p-2 rounded-full">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" className="h-4 w-4 text-ccfw-coral" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
||||
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M3 8l7.89 5.26a2 2 0 002.22 0L21 8M5 19h14a2 2 0 002-2V7a2 2 0 00-2-2H5a2 2 0 00-2 2v10a2 2 0 002 2z" />
|
||||
</svg>
|
||||
</div>
|
||||
<a
|
||||
href="mailto:info@ccfriendsofwildlife.org"
|
||||
className="text-sm text-ccfw-maroon font-medium hover:text-ccfw-teal transition-colors"
|
||||
>
|
||||
Contact CCFW
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
</CardContent>
|
||||
</Card>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</main>
|
||||
|
||||
<footer className="bg-ccfw-beige/90 text-ccfw-maroon py-8 mt-12">
|
||||
<div className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 text-center">
|
||||
<p className="text-sm">
|
||||
© {new Date().getFullYear()} Cape Coral Friends of Wildlife. All rights reserved.
|
||||
</p>
|
||||
<p className="text-sm mt-2">
|
||||
<a
|
||||
href="https://ccfriendsofwildlife.org/"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
className="hover:text-ccfw-teal transition-colors"
|
||||
>
|
||||
Visit our main website
|
||||
</a>
|
||||
</p>
|
||||
</div>
|
||||
</footer>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
57
app/map/page.tsx
Normal file
57
app/map/page.tsx
Normal file
@ -0,0 +1,57 @@
|
||||
import React from 'react';
|
||||
import { Map } from 'lucide-react';
|
||||
|
||||
export default function MapPage() {
|
||||
return (
|
||||
<div className="max-w-7xl mx-auto px-6 py-16 space-y-10">
|
||||
<header className="space-y-4">
|
||||
<div className="flex items-center gap-2 text-teal text-sm font-bold uppercase tracking-widest">
|
||||
<Map size={16} /> Burrow Map
|
||||
</div>
|
||||
<h1 className="text-4xl font-black text-white">Burrowing Owl Locations</h1>
|
||||
<p className="text-stone-400 text-lg max-w-2xl leading-relaxed">
|
||||
An interactive map of active burrowing owl burrows monitored by CCFW volunteers across Cape Coral.
|
||||
</p>
|
||||
</header>
|
||||
|
||||
{/* Map placeholder — interactive Leaflet map requires client component */}
|
||||
<div className="relative rounded-3xl overflow-hidden bg-surfaceGreen border border-white/5 shadow-2xl" style={{ height: 600 }}>
|
||||
<div className="absolute inset-0 flex flex-col items-center justify-center gap-6 text-stone-500">
|
||||
<div className="text-8xl">🗺️</div>
|
||||
<div className="text-center space-y-2">
|
||||
<p className="text-xl font-bold text-stone-300">Interactive Burrow Map</p>
|
||||
<p className="text-sm">
|
||||
Leaflet map with burrow markers loading from{' '}
|
||||
<code className="text-teal text-xs bg-black/30 px-2 py-0.5 rounded">/api/burrows</code>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
{/* Decorative grid pattern */}
|
||||
<div
|
||||
className="absolute inset-0 opacity-5"
|
||||
style={{
|
||||
backgroundImage:
|
||||
'linear-gradient(rgba(0,130,167,0.5) 1px, transparent 1px), linear-gradient(90deg, rgba(0,130,167,0.5) 1px, transparent 1px)',
|
||||
backgroundSize: '40px 40px',
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
|
||||
{/* Legend */}
|
||||
<div className="flex flex-wrap gap-6 px-4 text-sm text-stone-400">
|
||||
<div className="flex items-center gap-2">
|
||||
<div className="w-3 h-3 rounded-full bg-teal shadow-[0_0_8px_rgba(0,130,167,0.8)]" />
|
||||
Active burrow
|
||||
</div>
|
||||
<div className="flex items-center gap-2">
|
||||
<div className="w-3 h-3 rounded-full bg-stone-600" />
|
||||
Inactive burrow
|
||||
</div>
|
||||
<div className="flex items-center gap-2">
|
||||
<div className="w-3 h-3 rounded-full bg-gold" />
|
||||
Camera location
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
746
app/page.tsx
746
app/page.tsx
@ -1,640 +1,132 @@
|
||||
import React from 'react';
|
||||
import Link from 'next/link';
|
||||
import { Card, CardContent, CardHeader, CardTitle, CardDescription, CardFooter } from "@/components/ui/card";
|
||||
import { Button } from "@/components/ui/button";
|
||||
import { Tv2, Heart, ChevronRight, TreePine, Calendar } from 'lucide-react';
|
||||
import { api, Stream, Stat } from '@/lib/api';
|
||||
import StatsBar from './components/StatsBar';
|
||||
import StreamCard from './components/StreamCard';
|
||||
|
||||
// This would typically come from an API or database
|
||||
const livestreams = [
|
||||
{
|
||||
id: 1,
|
||||
name: "Cape Coral Burrowing Owl",
|
||||
location: "Cape Coral, FL",
|
||||
status: "Live",
|
||||
viewers: 128,
|
||||
description: "Watch these unique ground-dwelling owls at their burrows in Cape Coral. These protected birds are the official city bird of Cape Coral!"
|
||||
},
|
||||
{
|
||||
id: 2,
|
||||
name: "Burrowing Owl Habitat",
|
||||
location: "Cape Coral, FL",
|
||||
status: "Live",
|
||||
viewers: 95,
|
||||
description: "Observe burrowing owls in their natural habitat. Watch them hunt, nest, and interact with their environment."
|
||||
},
|
||||
{
|
||||
id: 3,
|
||||
name: "Owl Burrow Monitoring",
|
||||
location: "Cape Coral, FL",
|
||||
status: "Live",
|
||||
viewers: 67,
|
||||
description: "Monitor active burrowing owl burrows and learn about CCFW's conservation efforts to protect these amazing birds."
|
||||
},
|
||||
];
|
||||
async function getData(): Promise<{ stats: Stat | null; streams: Stream[] }> {
|
||||
try {
|
||||
const [stats, streams] = await Promise.all([api.getStats(), api.getStreams()]);
|
||||
return { stats, streams: streams.slice(0, 3) };
|
||||
} catch {
|
||||
return { stats: null, streams: [] };
|
||||
}
|
||||
}
|
||||
|
||||
export default async function Home() {
|
||||
const { stats, streams } = await getData();
|
||||
|
||||
export default function Home() {
|
||||
return (
|
||||
<div className="min-h-screen bg-background text-foreground">
|
||||
<header className="bg-gradient-to-r from-ccfw-beige/95 via-ccfw-beige/90 to-ccfw-beige/95 backdrop-blur-md sticky top-0 z-10 border-b border-ccfw-teal/30 shadow-sm">
|
||||
<div className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
|
||||
<div className="flex justify-between items-center h-16">
|
||||
{/* Logo and Brand */}
|
||||
<div className="flex items-center space-x-3">
|
||||
<div className="relative">
|
||||
<div className="absolute inset-0 bg-ccfw-teal/20 rounded-full blur-sm"></div>
|
||||
<div className="relative bg-gradient-to-br from-ccfw-teal to-ccfw-maroon p-2 rounded-full">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" className="h-6 w-6 text-white" viewBox="0 0 20 20" fill="currentColor">
|
||||
<path fillRule="evenodd" d="M10 18a8 8 0 100-16 8 8 0 000 16zm1-12a1 1 0 10-2 0v4a1 1 0 00.293.707l2.828 2.829a1 1 0 101.415-1.415L11 9.586V6z" clipRule="evenodd" />
|
||||
</svg>
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<h1 className="text-xl font-bold text-ccfw-teal tracking-tight">CCFW Livestreams</h1>
|
||||
<p className="text-xs text-ccfw-maroon font-semibold">Cape Coral Friends of Wildlife</p>
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
{/* Hero */}
|
||||
<section className="relative min-h-[80vh] flex items-center justify-center overflow-hidden">
|
||||
{/* Background gradient */}
|
||||
<div className="absolute inset-0 bg-gradient-to-br from-deepGreen via-surfaceGreen to-deepGreen" />
|
||||
<div className="absolute inset-0 bg-[radial-gradient(ellipse_at_center,_rgba(0,130,167,0.12)_0%,_transparent_70%)]" />
|
||||
{/* Decorative circles */}
|
||||
<div className="absolute bottom-0 left-0 w-[600px] h-[600px] bg-teal/5 rounded-full blur-3xl -translate-x-1/2 translate-y-1/2" />
|
||||
<div className="absolute top-0 right-0 w-[400px] h-[400px] bg-gold/5 rounded-full blur-3xl translate-x-1/2 -translate-y-1/2" />
|
||||
|
||||
{/* Navigation Actions */}
|
||||
<div className="flex items-center space-x-3">
|
||||
<a
|
||||
href="https://ccfriendsofwildlife.org/support/membership/"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
className="group relative px-4 py-2 bg-gradient-to-r from-ccfw-teal to-ccfw-maroon text-white font-medium rounded-lg shadow-sm hover:shadow-md transition-all duration-200 transform hover:scale-105"
|
||||
>
|
||||
<span className="relative z-10">Join/Renew</span>
|
||||
<div className="absolute inset-0 bg-gradient-to-r from-ccfw-maroon to-ccfw-teal rounded-lg opacity-0 group-hover:opacity-100 transition-opacity duration-200"></div>
|
||||
</a>
|
||||
<a
|
||||
href="https://ccfriendsofwildlife.org/volunteer/"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
className="group relative px-4 py-2 bg-gradient-to-r from-ccfw-coral to-orange-400 text-white font-medium rounded-lg shadow-sm hover:shadow-md transition-all duration-200 transform hover:scale-105"
|
||||
>
|
||||
<span className="relative z-10">Volunteer</span>
|
||||
<div className="absolute inset-0 bg-gradient-to-r from-orange-400 to-ccfw-coral rounded-lg opacity-0 group-hover:opacity-100 transition-opacity duration-200"></div>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</header>
|
||||
<main className="max-w-7xl mx-auto py-6 sm:px-6 lg:px-8">
|
||||
<div className="px-4 py-6 sm:px-0 space-y-12">
|
||||
{/* Hero Section */}
|
||||
<section className="relative">
|
||||
<div className="absolute inset-0 bg-gradient-to-br from-ccfw-teal/5 via-transparent to-ccfw-maroon/5 rounded-3xl"></div>
|
||||
<Card className="relative border-0 bg-gradient-to-br from-ccfw-maroon/90 via-ccfw-maroon/85 to-ccfw-maroon/90 backdrop-blur-md overflow-hidden shadow-2xl">
|
||||
<div className="absolute inset-0 bg-[url('https://ccfriendsofwildlife.org/wp-content/uploads/2020/07/Featured-image-home-page-1080x675.jpg')] opacity-15 bg-center bg-cover mix-blend-overlay"></div>
|
||||
<div className="absolute inset-0 bg-gradient-to-t from-black/20 via-transparent to-transparent"></div>
|
||||
|
||||
<CardHeader className="relative z-10 pb-8">
|
||||
<div className="flex items-center space-x-3 mb-4">
|
||||
<div className="h-1 w-12 bg-gradient-to-r from-ccfw-gold to-ccfw-coral rounded-full"></div>
|
||||
<span className="text-white text-sm font-medium tracking-wider uppercase">Live Wildlife Streams</span>
|
||||
</div>
|
||||
<CardTitle className="text-4xl md:text-5xl font-bold text-white leading-tight mb-4">
|
||||
Cape Coral Friends of
|
||||
<span className="block text-transparent bg-gradient-to-r from-ccfw-gold via-ccfw-coral to-orange-400 bg-clip-text">
|
||||
Wildlife Livestreams
|
||||
</span>
|
||||
</CardTitle>
|
||||
<CardDescription className="text-white/90 text-xl font-medium leading-relaxed">
|
||||
Dedicated to Protection, Preservation and Education
|
||||
</CardDescription>
|
||||
</CardHeader>
|
||||
|
||||
<CardContent className="relative z-10 space-y-6">
|
||||
<p className="text-white text-lg leading-relaxed font-medium">
|
||||
Discover the fascinating world of <span className="text-ccfw-gold font-semibold">burrowing owls</span>, the official city bird of Cape Coral.
|
||||
These unique ground-dwelling owls are active during the day and nest underground in burrows throughout our community.
|
||||
</p>
|
||||
<p className="text-white/90 text-lg leading-relaxed">
|
||||
Cape Coral Friends of Wildlife is dedicated to protecting these threatened birds through habitat preservation, burrow maintenance, and community education. With over 2,500 burrows maintained by our volunteers, we ensure these amazing owls thrive in our urban environment.
|
||||
</p>
|
||||
|
||||
<div className="flex flex-col sm:flex-row gap-4 pt-4">
|
||||
<div className="flex items-center space-x-6 text-white/80">
|
||||
<div className="flex items-center space-x-2">
|
||||
<div className="h-2 w-2 bg-ccfw-coral rounded-full animate-pulse"></div>
|
||||
<span className="text-sm font-medium">Live 24/7</span>
|
||||
</div>
|
||||
<div className="flex items-center space-x-2">
|
||||
<svg className="h-4 w-4 text-ccfw-gold" fill="currentColor" viewBox="0 0 20 20">
|
||||
<path fillRule="evenodd" d="M3 4a1 1 0 011-1h12a1 1 0 110 2H4a1 1 0 01-1-1zm0 4a1 1 0 011-1h12a1 1 0 110 2H4a1 1 0 01-1-1zm0 4a1 1 0 011-1h12a1 1 0 110 2H4a1 1 0 01-1-1z" clipRule="evenodd" />
|
||||
</svg>
|
||||
<span className="text-sm font-medium">HD Quality</span>
|
||||
</div>
|
||||
<div className="flex items-center space-x-2">
|
||||
<svg className="h-4 w-4 text-ccfw-teal" fill="currentColor" viewBox="0 0 20 20">
|
||||
<path fillRule="evenodd" d="M5.05 4.05a7 7 0 119.9 9.9L10 18.9l-4.95-4.95a7 7 0 010-9.9zM10 11a2 2 0 100-4 2 2 0 000 4z" clipRule="evenodd" />
|
||||
</svg>
|
||||
<span className="text-sm font-medium">Cape Coral, FL</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</CardContent>
|
||||
|
||||
<CardFooter className="relative z-10 pt-6">
|
||||
<a
|
||||
href="https://ccfriendsofwildlife.org/about-us/"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
className="group inline-flex items-center space-x-2 px-6 py-3 bg-gradient-to-r from-ccfw-gold to-ccfw-coral text-white font-semibold rounded-xl shadow-lg hover:shadow-xl transition-all duration-200 transform hover:scale-105"
|
||||
>
|
||||
<span>Learn more about CCFW</span>
|
||||
<svg className="h-4 w-4 transition-transform group-hover:translate-x-1" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M17 8l4 4m0 0l-4 4m4-4H3" />
|
||||
</svg>
|
||||
</a>
|
||||
</CardFooter>
|
||||
</Card>
|
||||
</section>
|
||||
|
||||
{/* Featured Owls Section */}
|
||||
<section className="space-y-8">
|
||||
<div className="text-center space-y-4">
|
||||
<div className="inline-flex items-center space-x-3">
|
||||
<div className="h-1 w-8 bg-gradient-to-r from-ccfw-teal to-ccfw-maroon rounded-full"></div>
|
||||
<h2 className="text-3xl md:text-4xl font-bold text-ccfw-teal tracking-tight">Featured Owls</h2>
|
||||
<div className="h-1 w-8 bg-gradient-to-r from-ccfw-maroon to-ccfw-teal rounded-full"></div>
|
||||
</div>
|
||||
<div className="flex items-center justify-center space-x-6 text-sm text-white font-medium">
|
||||
<div className="flex items-center space-x-2">
|
||||
<div className="h-2 w-2 bg-ccfw-teal rounded-full"></div>
|
||||
<span>Founded in 2001</span>
|
||||
</div>
|
||||
<div className="flex items-center space-x-2">
|
||||
<svg className="h-4 w-4 text-ccfw-gold" fill="currentColor" viewBox="0 0 20 20">
|
||||
<path d="M13 6a3 3 0 11-6 0 3 3 0 016 0zM18 8a2 2 0 11-4 0 2 2 0 014 0zM14 15a4 4 0 00-8 0v3h8v-3z" />
|
||||
</svg>
|
||||
<span>500+ Members</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="grid grid-cols-1 md:grid-cols-3 gap-8">
|
||||
{[
|
||||
{
|
||||
name: 'Burrowing Owl Facts',
|
||||
icon: '🦉',
|
||||
color: 'from-ccfw-teal to-ccfw-maroon',
|
||||
description: "Burrowing owls are small, long-legged owls that nest underground in burrows. Unlike most owls, they are active during the day and have bright yellow eyes. The City of Cape Coral has designated the burrowing owl as its official city bird."
|
||||
},
|
||||
{
|
||||
name: 'Owl Conservation',
|
||||
icon: '🌱',
|
||||
color: 'from-ccfw-maroon to-ccfw-teal',
|
||||
description: "CCFW volunteers maintain over 2,500 burrows throughout Cape Coral. These unique birds face threats from habitat loss and development. Our conservation efforts protect these amazing ground-dwelling owls."
|
||||
},
|
||||
{
|
||||
name: 'Owl Habitat',
|
||||
icon: '🏞️',
|
||||
color: 'from-ccfw-gold to-ccfw-coral',
|
||||
description: "Burrowing owls prefer open areas with low vegetation such as prairies, grasslands, and open areas of urban development. They create burrows that provide shelter for many other wildlife species as well."
|
||||
}
|
||||
].map((owlFeature) => (
|
||||
<Card key={owlFeature.name} className="group relative border-0 bg-gradient-to-br from-white/80 to-white/60 backdrop-blur-sm shadow-lg hover:shadow-xl transition-all duration-300 transform hover:scale-105 overflow-hidden">
|
||||
<div className={`absolute inset-0 bg-gradient-to-br ${owlFeature.color} opacity-0 group-hover:opacity-10 transition-opacity duration-300`}></div>
|
||||
|
||||
<CardHeader className="relative z-10 pb-4">
|
||||
<div className="flex items-center space-x-3 mb-3">
|
||||
<div className="text-3xl group-hover:scale-110 transition-transform duration-200">{owlFeature.icon}</div>
|
||||
<div>
|
||||
<CardTitle className="text-xl font-bold text-ccfw-teal group-hover:text-ccfw-maroon transition-colors">
|
||||
{owlFeature.name}
|
||||
</CardTitle>
|
||||
</div>
|
||||
</div>
|
||||
<div className={`h-0.5 w-full bg-gradient-to-r ${owlFeature.color} rounded-full`}></div>
|
||||
</CardHeader>
|
||||
|
||||
<CardContent className="relative z-10">
|
||||
<p className="text-ccfw-maroon leading-relaxed font-medium">
|
||||
{owlFeature.description}
|
||||
</p>
|
||||
</CardContent>
|
||||
</Card>
|
||||
))}
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{/* Live Cameras Section */}
|
||||
<section className="space-y-8">
|
||||
<div className="text-center space-y-4">
|
||||
<div className="inline-flex items-center space-x-3">
|
||||
<div className="h-1 w-8 bg-gradient-to-r from-ccfw-coral to-ccfw-gold rounded-full"></div>
|
||||
<h2 className="text-3xl md:text-4xl font-bold text-ccfw-teal tracking-tight">Live Cameras</h2>
|
||||
<div className="h-1 w-8 bg-gradient-to-r from-ccfw-gold to-ccfw-coral rounded-full"></div>
|
||||
</div>
|
||||
<div className="flex items-center justify-center space-x-2 text-sm text-white font-medium">
|
||||
<svg className="h-4 w-4 text-ccfw-teal" fill="currentColor" viewBox="0 0 20 20">
|
||||
<path fillRule="evenodd" d="M4 3a2 2 0 00-2 2v8a2 2 0 002 2h12a2 2 0 002-2V5a2 2 0 00-2-2H4zm3 2l3 3-3 3V8z" clipRule="evenodd" />
|
||||
</svg>
|
||||
<span>Powered by</span>
|
||||
<span className="font-bold text-transparent bg-gradient-to-r from-ccfw-gold to-ccfw-coral bg-clip-text">
|
||||
CCFW
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-8">
|
||||
{livestreams.map((stream) => (
|
||||
<Card key={stream.id} className="group relative border-0 bg-gradient-to-br from-white/90 to-white/70 backdrop-blur-sm shadow-lg hover:shadow-2xl transition-all duration-300 transform hover:scale-105 hover:-translate-y-2 overflow-hidden">
|
||||
{/* Status Indicator */}
|
||||
<div className="absolute top-4 right-4 z-20">
|
||||
<div className={`flex items-center space-x-2 px-3 py-1.5 rounded-full backdrop-blur-sm border ${
|
||||
stream.status === 'Live'
|
||||
? 'bg-emerald-500/20 border-emerald-400/30 text-emerald-700'
|
||||
: 'bg-gray-600/20 border-gray-500/30 text-gray-700'
|
||||
}`}>
|
||||
<div className={`h-2 w-2 rounded-full ${
|
||||
stream.status === 'Live' ? 'bg-emerald-500 animate-pulse' : 'bg-gray-400'
|
||||
}`}></div>
|
||||
<span className="text-xs font-bold tracking-wide uppercase">{stream.status}</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Background Gradient Overlay */}
|
||||
<div className="absolute inset-0 bg-gradient-to-br from-ccfw-teal/5 via-transparent to-ccfw-maroon/5 opacity-0 group-hover:opacity-100 transition-opacity duration-300"></div>
|
||||
|
||||
{/* Camera Preview Mockup */}
|
||||
<div className="relative h-48 bg-gradient-to-br from-ccfw-teal/10 to-ccfw-maroon/10 flex items-center justify-center overflow-hidden">
|
||||
<div className="absolute inset-0 bg-gradient-to-t from-black/20 to-transparent"></div>
|
||||
<div className="relative z-10 text-center space-y-3">
|
||||
<div className="mx-auto w-16 h-16 bg-white/20 backdrop-blur-sm rounded-full flex items-center justify-center">
|
||||
<svg className="h-8 w-8 text-ccfw-teal" fill="currentColor" viewBox="0 0 20 20">
|
||||
<path d="M2 6a2 2 0 012-2h6a2 2 0 012 2v8a2 2 0 01-2 2H4a2 2 0 01-2-2V6zM14.553 7.106A1 1 0 0014 8v4a1 1 0 00.553.894l2 1A1 1 0 0018 13V7a1 1 0 00-1.447-.894l-2 1z" />
|
||||
</svg>
|
||||
</div>
|
||||
<div className="text-white/80 text-sm font-medium">HD Live Stream</div>
|
||||
</div>
|
||||
|
||||
{/* Quality Badge */}
|
||||
<div className="absolute top-4 left-4 bg-black/60 text-white text-xs px-2 py-1 rounded backdrop-blur-sm">
|
||||
HD
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<CardHeader className="relative z-10 pt-6">
|
||||
<CardTitle className="text-xl font-bold text-ccfw-teal group-hover:text-ccfw-maroon transition-colors leading-tight">
|
||||
{stream.name}
|
||||
</CardTitle>
|
||||
<CardDescription className="text-ccfw-maroon font-medium flex items-center space-x-1">
|
||||
<svg className="h-4 w-4" fill="currentColor" viewBox="0 0 20 20">
|
||||
<path fillRule="evenodd" d="M5.05 4.05a7 7 0 119.9 9.9L10 18.9l-4.95-4.95a7 7 0 010-9.9zM10 11a2 2 0 100-4 2 2 0 000 4z" clipRule="evenodd" />
|
||||
</svg>
|
||||
<span>{stream.location}</span>
|
||||
</CardDescription>
|
||||
</CardHeader>
|
||||
|
||||
<CardContent className="relative z-10 space-y-4">
|
||||
<p className="text-ccfw-maroon leading-relaxed font-medium text-sm">
|
||||
{stream.description}
|
||||
</p>
|
||||
|
||||
{/* Viewer Count & Quality */}
|
||||
<div className="flex justify-between items-center">
|
||||
<div className="flex items-center space-x-4 text-xs">
|
||||
{stream.status === 'Live' && (
|
||||
<div className="flex items-center space-x-1 text-ccfw-teal font-semibold">
|
||||
<svg className="h-3 w-3" fill="currentColor" viewBox="0 0 20 20">
|
||||
<path d="M13 6a3 3 0 11-6 0 3 3 0 016 0zM18 8a2 2 0 11-4 0 2 2 0 014 0zM14 15a4 4 0 00-8 0v3h8v-3z" />
|
||||
</svg>
|
||||
<span>{stream.viewers} viewers</span>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
<div className="flex items-center space-x-1">
|
||||
<svg className="h-4 w-4 text-ccfw-gold" fill="currentColor" viewBox="0 0 20 20">
|
||||
<path fillRule="evenodd" d="M11.3 1.046A1 1 0 0112 2v5h4a1 1 0 01.82 1.573l-7 10A1 1 0 018 18v-5H4a1 1 0 01-.82-1.573l7-10a1 1 0 011.12-.38z" clipRule="evenodd" />
|
||||
</svg>
|
||||
<span className="text-xs font-semibold text-ccfw-maroon">HD</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Watch Button */}
|
||||
<Button
|
||||
asChild
|
||||
className={`w-full font-semibold py-3 rounded-xl shadow-md transition-all duration-200 ${
|
||||
stream.status === 'Live'
|
||||
? 'bg-gradient-to-r from-ccfw-teal to-ccfw-maroon text-white hover:shadow-lg hover:scale-105'
|
||||
: 'bg-gray-300 text-gray-600 cursor-not-allowed'
|
||||
}`}
|
||||
disabled={stream.status !== 'Live'}
|
||||
>
|
||||
<Link href={`/livestream/${stream.id}`} className="flex items-center justify-center space-x-2">
|
||||
{stream.status === 'Live' ? (
|
||||
<>
|
||||
<svg className="h-4 w-4" fill="currentColor" viewBox="0 0 20 20">
|
||||
<path d="M10 12l-6-4h12l-6 4z" />
|
||||
<path d="M10 8l6 4H4l6-4z" />
|
||||
</svg>
|
||||
<span>Watch Live</span>
|
||||
</>
|
||||
) : (
|
||||
<>
|
||||
<svg className="h-4 w-4" fill="currentColor" viewBox="0 0 20 20">
|
||||
<path fillRule="evenodd" d="M10 18a8 8 0 100-16 8 8 0 000 16zM8 7a1 1 0 00-1 1v4a1 1 0 001 1h4a1 1 0 001-1V8a1 1 0 00-1-1H8z" clipRule="evenodd" />
|
||||
</svg>
|
||||
<span>Offline</span>
|
||||
</>
|
||||
)}
|
||||
</Link>
|
||||
</Button>
|
||||
</CardContent>
|
||||
</Card>
|
||||
))}
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{/* Support Our Mission Section */}
|
||||
<section className="relative bg-gradient-to-br from-ccfw-beige/20 via-ccfw-beige/10 to-transparent p-8 rounded-3xl border border-ccfw-teal/30 shadow-lg overflow-hidden">
|
||||
<div className="absolute inset-0 bg-gradient-to-br from-ccfw-teal/5 to-ccfw-maroon/5"></div>
|
||||
|
||||
<div className="relative z-10 flex flex-col lg:flex-row gap-12 items-center">
|
||||
{/* Content Section */}
|
||||
<div className="lg:w-1/2 space-y-6">
|
||||
<div className="space-y-4">
|
||||
<div className="inline-flex items-center space-x-3">
|
||||
<div className="h-1 w-8 bg-gradient-to-r from-ccfw-teal to-ccfw-maroon rounded-full"></div>
|
||||
<h2 className="text-3xl md:text-4xl font-bold text-white tracking-tight">Support Our Mission</h2>
|
||||
</div>
|
||||
<p className="text-lg text-white leading-relaxed font-medium">
|
||||
Cape Coral Friends of Wildlife is a volunteer organization founded in 2001. With over 500 members and an engaged group of volunteers, we work to preserve and enhance the habitats of protected wildlife.
|
||||
</p>
|
||||
<p className="text-lg text-white/90 leading-relaxed font-medium">
|
||||
Your support helps us continue our conservation efforts and educational programs that benefit the unique wildlife of Southwest Florida.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
{/* Action Buttons */}
|
||||
<div className="flex flex-col sm:flex-row gap-4">
|
||||
<a
|
||||
href="https://ccfriendsofwildlife.org/support/membership/"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
className="group relative px-6 py-3 bg-gradient-to-r from-ccfw-gold to-amber-500 text-white font-bold rounded-xl shadow-lg hover:shadow-xl transition-all duration-200 transform hover:scale-105 overflow-hidden"
|
||||
>
|
||||
<span className="relative z-10 flex items-center justify-center space-x-2">
|
||||
<svg className="h-5 w-5" fill="currentColor" viewBox="0 0 20 20">
|
||||
<path d="M13 6a3 3 0 11-6 0 3 3 0 016 0zM18 8a2 2 0 11-4 0 2 2 0 014 0zM14 15a4 4 0 00-8 0v3h8v-3z" />
|
||||
</svg>
|
||||
<span>Become a Member</span>
|
||||
</span>
|
||||
<div className="absolute inset-0 bg-gradient-to-r from-amber-500 to-ccfw-gold rounded-xl opacity-0 group-hover:opacity-100 transition-opacity duration-200"></div>
|
||||
</a>
|
||||
|
||||
<a
|
||||
href="https://ccfriendsofwildlife.org/donate-to-ccfw/"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
className="group relative px-6 py-3 bg-gradient-to-r from-ccfw-coral to-rose-500 text-white font-bold rounded-xl shadow-lg hover:shadow-xl transition-all duration-200 transform hover:scale-105 overflow-hidden"
|
||||
>
|
||||
<span className="relative z-10 flex items-center justify-center space-x-2">
|
||||
<svg className="h-5 w-5" fill="currentColor" viewBox="0 0 20 20">
|
||||
<path fillRule="evenodd" d="M3.172 5.172a4 4 0 015.656 0L10 6.343l1.172-1.171a4 4 0 115.656 5.656L10 17.657l-6.828-6.829a4 4 0 010-5.656z" clipRule="evenodd" />
|
||||
</svg>
|
||||
<span>Donate Today</span>
|
||||
</span>
|
||||
<div className="absolute inset-0 bg-gradient-to-r from-rose-500 to-ccfw-coral rounded-xl opacity-0 group-hover:opacity-100 transition-opacity duration-200"></div>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Stats Card */}
|
||||
<div className="lg:w-1/2 flex justify-center">
|
||||
<div className="relative w-full max-w-md">
|
||||
{/* Background Glow */}
|
||||
<div className="absolute inset-0 bg-gradient-to-br from-ccfw-teal/20 to-ccfw-maroon/20 rounded-3xl blur-xl"></div>
|
||||
|
||||
<div className="relative bg-gradient-to-br from-white/90 to-white/70 backdrop-blur-sm p-8 rounded-3xl border border-white/30 shadow-xl">
|
||||
{/* Header */}
|
||||
<div className="text-center mb-8">
|
||||
<div className="inline-flex items-center space-x-2 mb-3">
|
||||
<svg className="h-6 w-6 text-ccfw-gold" fill="currentColor" viewBox="0 0 20 20">
|
||||
<path fillRule="evenodd" d="M6 2a1 1 0 00-1 1v1H4a2 2 0 00-2 2v10a2 2 0 002 2h12a2 2 0 002-2V6a2 2 0 00-2-2h-1V3a1 1 0 10-2 0v1H7V3a1 1 0 00-1-1zm0 5a1 1 0 000 2h8a1 1 0 100-2H6z" clipRule="evenodd" />
|
||||
</svg>
|
||||
<span className="text-sm font-bold text-white tracking-wider uppercase">Impact This Year</span>
|
||||
</div>
|
||||
<h3 className="text-2xl font-bold text-ccfw-teal">Volunteer Hours</h3>
|
||||
</div>
|
||||
|
||||
{/* Main Stat */}
|
||||
<div className="text-center mb-6">
|
||||
<div className="relative">
|
||||
<div className="absolute inset-0 bg-gradient-to-r from-ccfw-coral to-rose-400 rounded-full blur-2xl opacity-30"></div>
|
||||
<div className="relative text-7xl md:text-8xl font-black text-transparent bg-gradient-to-r from-ccfw-coral to-rose-500 bg-clip-text">
|
||||
836
|
||||
</div>
|
||||
</div>
|
||||
<p className="text-white font-semibold mt-2">And counting...</p>
|
||||
</div>
|
||||
|
||||
{/* CTA */}
|
||||
<div className="text-center">
|
||||
<a
|
||||
href="https://ccfriendsofwildlife.org/volunteer/"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
className="inline-flex items-center space-x-2 px-6 py-3 bg-gradient-to-r from-ccfw-teal to-ccfw-maroon text-white font-semibold rounded-xl shadow-md hover:shadow-lg transition-all duration-200 transform hover:scale-105"
|
||||
>
|
||||
<svg className="h-4 w-4" fill="currentColor" viewBox="0 0 20 20">
|
||||
<path d="M9 12l2 2 4-4m6 2a9 9 0 11-18 0 9 9 0 0118 0z" />
|
||||
<path d="M9.049 2.927c.3-.921 1.603-.921 1.902 0l1.07 3.292a1 1 0 00.95.69h3.462c.969 0 1.371 1.24.588 1.81l-2.8 2.034a1 1 0 00-.364 1.118l1.07 3.292c.3.921-.755 1.688-1.54 1.118l-2.8-2.034a1 1 0 00-1.175 0l-2.8 2.034c-.784.57-1.838-.197-1.539-1.118l1.07-3.292a1 1 0 00-.364-1.118L2.98 8.72c-.783-.57-.38-1.81.588-1.81h3.461a1 1 0 00.951-.69l1.07-3.292z" />
|
||||
</svg>
|
||||
<span>Join Our Team</span>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
</div>
|
||||
</main>
|
||||
{/* Modern Footer */}
|
||||
<footer className="relative bg-gradient-to-br from-ccfw-beige/90 via-ccfw-beige/95 to-white/90 backdrop-blur-sm mt-20 border-t border-ccfw-teal/30">
|
||||
<div className="absolute inset-0 bg-gradient-to-br from-ccfw-teal/5 to-transparent"></div>
|
||||
|
||||
<div className="relative max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 py-12">
|
||||
{/* Main Footer Content */}
|
||||
<div className="grid grid-cols-1 md:grid-cols-4 gap-8 mb-12">
|
||||
{/* Organization Info */}
|
||||
<div className="md:col-span-2 space-y-6">
|
||||
<div className="flex items-center space-x-3">
|
||||
<div className="relative">
|
||||
<div className="absolute inset-0 bg-ccfw-teal/20 rounded-full blur-sm"></div>
|
||||
<div className="relative bg-gradient-to-br from-ccfw-teal to-ccfw-maroon p-2 rounded-full">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" className="h-6 w-6 text-white" viewBox="0 0 20 20" fill="currentColor">
|
||||
<path fillRule="evenodd" d="M10 18a8 8 0 100-16 8 8 0 000 16zm1-12a1 1 0 10-2 0v4a1 1 0 00.293.707l2.828 2.829a1 1 0 101.415-1.415L11 9.586V6z" clipRule="evenodd" />
|
||||
</svg>
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<h3 className="text-xl font-bold text-ccfw-teal tracking-tight">Cape Coral Friends of Wildlife</h3>
|
||||
<p className="text-sm text-ccfw-maroon font-medium">CCFW • Est. 2001</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<p className="text-ccfw-maroon leading-relaxed font-medium max-w-md">
|
||||
A volunteer organization dedicated to the preservation of wildlife in Cape Coral, Florida. We protect and enhance habitats for protected species through education and conservation.
|
||||
</p>
|
||||
|
||||
<div className="flex items-center space-x-4">
|
||||
<div className="flex items-center space-x-2 bg-ccfw-teal/10 px-3 py-1.5 rounded-full">
|
||||
<svg className="h-4 w-4 text-ccfw-teal" fill="currentColor" viewBox="0 0 20 20">
|
||||
<path fillRule="evenodd" d="M6.267 3.455a3.066 3.066 0 001.745-.723 3.066 3.066 0 013.976 0 3.066 3.066 0 001.745.723 3.066 3.066 0 012.812 2.812c.051.643.304 1.254.723 1.745a3.066 3.066 0 010 3.976 3.066 3.066 0 00-.723 1.745 3.066 3.066 0 01-2.812 2.812 3.066 3.066 0 00-1.745.723 3.066 3.066 0 01-3.976 0 3.066 3.066 0 00-1.745-.723 3.066 3.066 0 01-2.812-2.812 3.066 3.066 0 00-.723-1.745 3.066 3.066 0 010-3.976 3.066 3.066 0 00.723-1.745 3.066 3.066 0 012.812-2.812zm7.44 5.252a1 1 0 00-1.414-1.414L9 10.586 7.707 9.293a1 1 0 00-1.414 1.414l2 2a1 1 0 001.414 0l4-4z" clipRule="evenodd" />
|
||||
</svg>
|
||||
<span className="text-xs font-bold text-ccfw-teal">501(c)(3) Nonprofit</span>
|
||||
</div>
|
||||
<div className="flex items-center space-x-2 bg-ccfw-gold/20 px-3 py-1.5 rounded-full">
|
||||
<svg className="h-4 w-4 text-ccfw-gold" fill="currentColor" viewBox="0 0 20 20">
|
||||
<path d="M9 12l2 2 4-4m6 2a9 9 0 11-18 0 9 9 0 0118 0z" />
|
||||
</svg>
|
||||
<span className="text-xs font-bold text-white">500+ Members</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Quick Links */}
|
||||
<div className="space-y-4">
|
||||
<h3 className="text-lg font-bold text-ccfw-teal tracking-tight">Quick Links</h3>
|
||||
<ul className="space-y-3">
|
||||
<li>
|
||||
<a
|
||||
href="https://ccfriendsofwildlife.org/"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
className="group flex items-center space-x-2 text-ccfw-maroon hover:text-ccfw-teal transition-colors font-medium"
|
||||
>
|
||||
<svg className="h-4 w-4 transition-transform group-hover:translate-x-1" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M10 6H6a2 2 0 00-2 2v10a2 2 0 002 2h10a2 2 0 002-2v-4M14 4h6m0 0v6m0-6L10 14" />
|
||||
</svg>
|
||||
<span>Main Website</span>
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<a
|
||||
href="https://ccfriendsofwildlife.org/events-and-programs/"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
className="group flex items-center space-x-2 text-ccfw-maroon hover:text-ccfw-teal transition-colors font-medium"
|
||||
>
|
||||
<svg className="h-4 w-4 transition-transform group-hover:translate-x-1" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M10 6H6a2 2 0 00-2 2v10a2 2 0 002 2h10a2 2 0 002-2v-4M14 4h6m0 0v6m0-6L10 14" />
|
||||
</svg>
|
||||
<span>Events & Programs</span>
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<a
|
||||
href="https://ccfriendsofwildlife.org/burrowing-owls/"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
className="group flex items-center space-x-2 text-ccfw-maroon hover:text-ccfw-teal transition-colors font-medium"
|
||||
>
|
||||
<svg className="h-4 w-4 transition-transform group-hover:translate-x-1" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M10 6H6a2 2 0 00-2 2v10a2 2 0 002 2h10a2 2 0 002-2v-4M14 4h6m0 0v6m0-6L10 14" />
|
||||
</svg>
|
||||
<span>Burrowing Owls</span>
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<a
|
||||
href="https://ccfriendsofwildlife.org/about-us/"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
className="group flex items-center space-x-2 text-ccfw-maroon hover:text-ccfw-teal transition-colors font-medium"
|
||||
>
|
||||
<svg className="h-4 w-4 transition-transform group-hover:translate-x-1" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M10 6H6a2 2 0 00-2 2v10a2 2 0 002 2h10a2 2 0 002-2v-4M14 4h6m0 0v6m0-6L10 14" />
|
||||
</svg>
|
||||
<span>About Us</span>
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
{/* Contact & Social */}
|
||||
<div className="space-y-4">
|
||||
<h3 className="text-lg font-bold text-ccfw-teal tracking-tight">Get In Touch</h3>
|
||||
|
||||
<div className="space-y-4">
|
||||
<div className="flex items-center space-x-3 p-3 bg-white/50 rounded-xl border border-ccfw-teal/20">
|
||||
<div className="bg-gradient-to-r from-ccfw-teal to-ccfw-maroon p-2 rounded-lg">
|
||||
<svg className="h-4 w-4 text-white" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M3 5a2 2 0 012-2h3.28a1 1 0 01.948.684l1.498 4.493a1 1 0 01-.502 1.21l-2.257 1.13a11.042 11.042 0 005.516 5.516l1.13-2.257a1 1 0 011.21-.502l4.493 1.498a1 1 0 01.684.949V19a2 2 0 01-2 2h-1C9.716 21 3 14.284 3 6V5z" />
|
||||
</svg>
|
||||
</div>
|
||||
<div>
|
||||
<p className="text-xs text-ccfw-maroon font-medium">Call Us</p>
|
||||
<a
|
||||
href="tel:239-980-2593"
|
||||
className="text-ccfw-maroon font-bold hover:text-ccfw-teal transition-colors"
|
||||
>
|
||||
(239) 980-2593
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="space-y-3">
|
||||
<p className="text-sm font-bold text-ccfw-teal tracking-wide uppercase">Follow Us</p>
|
||||
<div className="flex space-x-3">
|
||||
<a
|
||||
href="https://www.facebook.com/CCFriendsofWildlife"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
className="group p-3 bg-gradient-to-r from-blue-600 to-blue-700 text-white rounded-xl shadow-md hover:shadow-lg transition-all duration-200 transform hover:scale-110"
|
||||
>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" className="h-5 w-5" fill="currentColor" viewBox="0 0 24 24">
|
||||
<path d="M9 8h-3v4h3v12h5v-12h3.642l.358-4h-4v-1.667c0-.955.192-1.333 1.115-1.333h2.885v-5h-3.808c-3.596 0-5.192 1.583-5.192 4.615v3.385z" />
|
||||
</svg>
|
||||
</a>
|
||||
<a
|
||||
href="https://www.instagram.com/ccfriendsofwildlife/"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
className="group p-3 bg-gradient-to-r from-pink-500 via-red-500 to-yellow-500 text-white rounded-xl shadow-md hover:shadow-lg transition-all duration-200 transform hover:scale-110"
|
||||
>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" className="h-5 w-5" fill="currentColor" viewBox="0 0 24 24">
|
||||
<path d="M12 2.163c3.204 0 3.584.012 4.85.07 3.252.148 4.771 1.691 4.919 4.919.058 1.265.069 1.645.069 4.849 0 3.205-.012 3.584-.069 4.849-.149 3.225-1.664 4.771-4.919 4.919-1.266.058-1.644.07-4.85.07-3.204 0-3.584-.012-4.849-.07-3.26-.149-4.771-1.699-4.919-4.92-.058-1.265-.07-1.644-.07-4.849 0-3.204.013-3.583.07-4.849.149-3.227 1.664-4.771 4.919-4.919 1.266-.057 1.645-.069 4.849-.069zm0-2.163c-3.259 0-3.667.014-4.947.072-4.358.2-6.78 2.618-6.98 6.98-.059 1.281-.073 1.689-.073 4.948 0 3.259.014 3.668.072 4.948.2 4.358 2.618 6.78 6.98 6.98 1.281.058 1.689.072 4.948.072 3.259 0 3.668-.014 4.948-.072 4.354-.2 6.782-2.618 6.979-6.98.059-1.28.073-1.689.073-4.948 0-3.259-.014-3.667-.072-4.947-.196-4.354-2.617-6.78-6.979-6.98-1.281-.059-1.69-.073-4.949-.073zm0 5.838c-3.403 0-6.162 2.759-6.162 6.162s2.759 6.163 6.162 6.163 6.162-2.759 6.162-6.163c0-3.403-2.759-6.162-6.162-6.162zm0 10.162c-2.209 0-4-1.79-4-4 0-2.209 1.791-4 4-4s4 1.791 4 4c0 2.21-1.791 4-4 4zm6.406-11.845c-.796 0-1.441.645-1.441 1.44s.645 1.44 1.441 1.44c.795 0 1.439-.645 1.439-1.44s-.644-1.44-1.439-1.44z" />
|
||||
</svg>
|
||||
</a>
|
||||
<a
|
||||
href="https://www.youtube.com/channel/UC-VIPk6M1K4xEA-gXv6_cZQ"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
className="group p-3 bg-gradient-to-r from-red-600 to-red-700 text-white rounded-xl shadow-md hover:shadow-lg transition-all duration-200 transform hover:scale-110"
|
||||
>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" className="h-5 w-5" fill="currentColor" viewBox="0 0 24 24">
|
||||
<path d="M19.615 3.184c-3.604-.246-11.631-.245-15.23 0-3.897.266-4.356 2.62-4.385 8.816.029 6.185.484 8.549 4.385 8.816 3.6.245 11.626.246 15.23 0 3.897-.266 4.356-2.62 4.385-8.816-.029-6.185-.484-8.549-4.385-8.816zm-10.615 12.816v-8l8 3.993-8 4.007z" />
|
||||
</svg>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="relative z-10 max-w-5xl mx-auto px-6 text-center space-y-8">
|
||||
{/* Live badge */}
|
||||
<div className="inline-flex items-center gap-2 bg-red-500/10 border border-red-500/30 px-4 py-1.5 rounded-full text-sm text-red-400 font-bold animate-pulse">
|
||||
<span className="w-2 h-2 rounded-full bg-red-500" />
|
||||
Cameras Live Now
|
||||
</div>
|
||||
|
||||
{/* Footer Bottom */}
|
||||
<div className="pt-8 border-t border-ccfw-teal/20">
|
||||
<div className="flex flex-col md:flex-row justify-between items-center space-y-4 md:space-y-0">
|
||||
<div className="text-center md:text-left">
|
||||
<p className="text-ccfw-maroon font-medium">
|
||||
© 2024 Cape Coral Friends of Wildlife. All rights reserved.
|
||||
</p>
|
||||
<p className="text-xs text-ccfw-maroon mt-1">
|
||||
Made with ❤️ for Florida's wildlife
|
||||
</p>
|
||||
</div>
|
||||
<div className="flex items-center space-x-6 text-xs text-ccfw-maroon font-medium">
|
||||
<span>Privacy Policy</span>
|
||||
<span>Terms of Service</span>
|
||||
<span>Accessibility</span>
|
||||
</div>
|
||||
</div>
|
||||
<h1 className="text-5xl md:text-7xl font-black tracking-tight text-white leading-none">
|
||||
Watch Cape Coral's<br />
|
||||
<span className="text-transparent bg-clip-text bg-gradient-to-r from-teal to-gold">
|
||||
Burrowing Owls
|
||||
</span>
|
||||
<br />Live
|
||||
</h1>
|
||||
|
||||
<p className="text-stone-400 text-lg md:text-xl max-w-2xl mx-auto leading-relaxed">
|
||||
Free, 24/7 wildlife cameras brought to you by Cape Coral Friends of Wildlife. Watch, learn, and help protect Florida's native species.
|
||||
</p>
|
||||
|
||||
<div className="flex flex-col sm:flex-row gap-4 justify-center pt-4">
|
||||
<Link
|
||||
href="/streams"
|
||||
className="inline-flex items-center gap-2 bg-teal hover:bg-tealLight text-white font-bold px-8 py-4 rounded-xl shadow-xl shadow-teal/20 transition-all active:scale-95"
|
||||
>
|
||||
<Tv2 size={20} /> Watch Live Cams
|
||||
</Link>
|
||||
<Link
|
||||
href="/donate"
|
||||
className="inline-flex items-center gap-2 bg-gold/10 border border-gold/30 hover:bg-gold/20 text-gold font-bold px-8 py-4 rounded-xl transition-all active:scale-95"
|
||||
>
|
||||
<Heart size={18} /> Support the Mission
|
||||
</Link>
|
||||
</div>
|
||||
</div>
|
||||
</footer>
|
||||
</section>
|
||||
|
||||
{/* Stats Bar */}
|
||||
{stats && (
|
||||
<section className="max-w-6xl mx-auto px-6 -mt-8 relative z-10">
|
||||
<StatsBar stats={stats} />
|
||||
</section>
|
||||
)}
|
||||
|
||||
{/* Latest Streams */}
|
||||
{streams.length > 0 && (
|
||||
<section className="max-w-7xl mx-auto px-6 py-24 space-y-10">
|
||||
<div className="flex items-end justify-between">
|
||||
<div>
|
||||
<h2 className="text-3xl font-black text-white">Live Cameras</h2>
|
||||
<p className="text-stone-400 mt-1">Watch our wildlife cams in real time</p>
|
||||
</div>
|
||||
<Link href="/streams" className="flex items-center gap-1 text-teal text-sm font-semibold hover:gap-2 transition-all">
|
||||
View all <ChevronRight size={16} />
|
||||
</Link>
|
||||
</div>
|
||||
<div className="grid grid-cols-1 md:grid-cols-3 gap-6">
|
||||
{streams.map((s) => <StreamCard key={s.id} stream={s} />)}
|
||||
</div>
|
||||
</section>
|
||||
)}
|
||||
|
||||
{/* Mission CTA grid */}
|
||||
<section className="max-w-7xl mx-auto px-6 pb-24 grid grid-cols-1 md:grid-cols-3 gap-6">
|
||||
{[
|
||||
{
|
||||
icon: TreePine,
|
||||
title: 'Wildlife Guide',
|
||||
desc: 'Learn about burrowing owls, gopher tortoises, scrub-jays, and manatees.',
|
||||
href: '/wildlife',
|
||||
cta: 'Explore Species',
|
||||
color: 'text-emerald-400',
|
||||
},
|
||||
{
|
||||
icon: Heart,
|
||||
title: 'Support CCFW',
|
||||
desc: 'Your donation funds cameras, land preservation, and volunteer programs.',
|
||||
href: '/donate',
|
||||
cta: 'Donate Now',
|
||||
color: 'text-gold',
|
||||
},
|
||||
{
|
||||
icon: Calendar,
|
||||
title: 'Upcoming Events',
|
||||
desc: 'Join cleanups, educational walks, and community conservation events.',
|
||||
href: '/events',
|
||||
cta: 'See Events',
|
||||
color: 'text-teal',
|
||||
},
|
||||
].map(({ icon: Icon, title, desc, href, cta, color }) => (
|
||||
<div key={href} className="bg-surfaceGreen border border-white/5 rounded-2xl p-8 hover:border-white/10 transition-all group">
|
||||
<Icon size={32} className={`${color} mb-5 group-hover:scale-110 transition-transform`} />
|
||||
<h3 className="font-bold text-white text-xl mb-2">{title}</h3>
|
||||
<p className="text-stone-400 text-sm leading-relaxed mb-6">{desc}</p>
|
||||
<Link href={href} className="inline-flex items-center gap-1 text-sm font-bold text-stone-300 hover:text-white group-hover:gap-2 transition-all">
|
||||
{cta} <ChevronRight size={14} />
|
||||
</Link>
|
||||
</div>
|
||||
))}
|
||||
</section>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
58
app/streams/[id]/VideoPlayer.tsx
Normal file
58
app/streams/[id]/VideoPlayer.tsx
Normal file
@ -0,0 +1,58 @@
|
||||
'use client';
|
||||
import React, { useEffect, useRef } from 'react';
|
||||
import { Radio } from 'lucide-react';
|
||||
|
||||
interface Props {
|
||||
hlsUrl?: string;
|
||||
thumbnailUrl?: string;
|
||||
}
|
||||
|
||||
export default function VideoPlayer({ hlsUrl, thumbnailUrl }: Props) {
|
||||
const videoRef = useRef<HTMLVideoElement>(null);
|
||||
|
||||
useEffect(() => {
|
||||
if (!hlsUrl || !videoRef.current) return;
|
||||
const video = videoRef.current;
|
||||
|
||||
if (video.canPlayType('application/vnd.apple.mpegurl')) {
|
||||
video.src = hlsUrl;
|
||||
return;
|
||||
}
|
||||
|
||||
import('hls.js').then(({ default: Hls }) => {
|
||||
if (Hls.isSupported()) {
|
||||
const hls = new Hls();
|
||||
hls.loadSource(hlsUrl);
|
||||
hls.attachMedia(video);
|
||||
return () => hls.destroy();
|
||||
}
|
||||
});
|
||||
}, [hlsUrl]);
|
||||
|
||||
if (!hlsUrl) {
|
||||
return (
|
||||
<div className="relative aspect-video bg-black/40 rounded-2xl border border-white/5 flex flex-col items-center justify-center gap-4 text-stone-500">
|
||||
<Radio size={48} className="text-stone-600" />
|
||||
<p className="text-sm font-medium">Stream offline — no source available</p>
|
||||
{thumbnailUrl && (
|
||||
// eslint-disable-next-line @next/next/no-img-element
|
||||
<img src={thumbnailUrl} alt="Stream thumbnail" className="absolute inset-0 w-full h-full object-cover rounded-2xl opacity-20" />
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="relative aspect-video rounded-2xl overflow-hidden bg-black shadow-2xl shadow-black/60">
|
||||
<video
|
||||
ref={videoRef}
|
||||
controls
|
||||
autoPlay
|
||||
muted
|
||||
playsInline
|
||||
className="w-full h-full"
|
||||
poster={thumbnailUrl}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
86
app/streams/[id]/page.tsx
Normal file
86
app/streams/[id]/page.tsx
Normal file
@ -0,0 +1,86 @@
|
||||
import React from 'react';
|
||||
import { notFound } from 'next/navigation';
|
||||
import { MapPin, Users, ArrowLeft } from 'lucide-react';
|
||||
import Link from 'next/link';
|
||||
import { api, Campaign } from '@/lib/api';
|
||||
import VideoPlayer from './VideoPlayer';
|
||||
import DonationCard from '../../components/DonationCard';
|
||||
|
||||
export default async function StreamDetailPage({ params }: { params: { id: string } }) {
|
||||
let stream;
|
||||
let campaigns: Campaign[] = [];
|
||||
try {
|
||||
[stream, campaigns] = await Promise.all([
|
||||
api.getStream(params.id),
|
||||
api.getCampaigns(),
|
||||
]);
|
||||
} catch {
|
||||
notFound();
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="max-w-7xl mx-auto px-6 py-10 space-y-8">
|
||||
{/* Back */}
|
||||
<Link href="/streams" className="inline-flex items-center gap-2 text-stone-400 hover:text-white text-sm font-medium transition-colors">
|
||||
<ArrowLeft size={16} /> Back to all cameras
|
||||
</Link>
|
||||
|
||||
{/* Status bar */}
|
||||
<div className="flex flex-wrap items-center gap-4">
|
||||
<span className={`flex items-center gap-2 px-3 py-1 rounded-full text-xs font-bold uppercase ${
|
||||
stream.status === 'live' ? 'bg-red-500/20 text-red-400' : 'bg-stone-700/40 text-stone-400'
|
||||
}`}>
|
||||
{stream.status === 'live' && <span className="w-1.5 h-1.5 rounded-full bg-red-500 animate-pulse" />}
|
||||
{stream.status === 'live' ? 'Live' : 'Offline'}
|
||||
</span>
|
||||
{stream.location && (
|
||||
<span className="flex items-center gap-1.5 text-stone-400 text-sm">
|
||||
<MapPin size={14} /> {stream.location}
|
||||
</span>
|
||||
)}
|
||||
{stream.viewerCount > 0 && (
|
||||
<span className="flex items-center gap-1.5 text-stone-400 text-sm">
|
||||
<Users size={14} /> {stream.viewerCount.toLocaleString()} watching
|
||||
</span>
|
||||
)}
|
||||
</div>
|
||||
|
||||
<div className="grid grid-cols-1 xl:grid-cols-3 gap-8">
|
||||
{/* Main video + info */}
|
||||
<div className="xl:col-span-2 space-y-6">
|
||||
<VideoPlayer hlsUrl={stream.hlsUrl} thumbnailUrl={stream.thumbnailUrl} />
|
||||
<div className="space-y-3">
|
||||
<h1 className="text-3xl font-black text-white">{stream.name}</h1>
|
||||
{stream.description && (
|
||||
<p className="text-stone-400 leading-relaxed">{stream.description}</p>
|
||||
)}
|
||||
</div>
|
||||
|
||||
{/* Wildlife facts panel */}
|
||||
<div className="bg-surfaceGreen border border-white/5 rounded-2xl p-6 space-y-4">
|
||||
<h3 className="font-bold text-gold text-sm uppercase tracking-widest">Burrowing Owl Facts</h3>
|
||||
<ul className="space-y-3 text-sm text-stone-300 leading-relaxed">
|
||||
<li className="flex gap-3"><span className="text-teal font-bold shrink-0">•</span>Burrowing owls are the official city bird of Cape Coral, FL.</li>
|
||||
<li className="flex gap-3"><span className="text-teal font-bold shrink-0">•</span>Unlike most owls, they are active during the day and nest underground.</li>
|
||||
<li className="flex gap-3"><span className="text-teal font-bold shrink-0">•</span>They are a Species of Special Concern in Florida — development threatens their habitat.</li>
|
||||
<li className="flex gap-3"><span className="text-teal font-bold shrink-0">•</span>CCFW monitors over 2,000 active burrow sites across Cape Coral.</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Sidebar: Donate */}
|
||||
<div className="space-y-6">
|
||||
<div className="bg-surfaceGreen border border-white/5 rounded-2xl p-6 space-y-4">
|
||||
<h3 className="font-bold text-white">Support the Cameras</h3>
|
||||
<p className="text-stone-400 text-sm leading-relaxed">
|
||||
These cameras run 24/7 thanks to donations from wildlife lovers like you.
|
||||
</p>
|
||||
</div>
|
||||
{campaigns.slice(0, 1).map((c) => (
|
||||
<DonationCard key={c.id} campaign={c} />
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
59
app/streams/page.tsx
Normal file
59
app/streams/page.tsx
Normal file
@ -0,0 +1,59 @@
|
||||
import React from 'react';
|
||||
import { Radio } from 'lucide-react';
|
||||
import { api, Stream } from '@/lib/api';
|
||||
import StreamCard from '../components/StreamCard';
|
||||
|
||||
async function getStreams(): Promise<Stream[]> {
|
||||
try { return await api.getStreams(); }
|
||||
catch { return []; }
|
||||
}
|
||||
|
||||
export default async function StreamsPage() {
|
||||
const streams = await getStreams();
|
||||
const live = streams.filter((s) => s.status === 'live');
|
||||
const offline = streams.filter((s) => s.status !== 'live');
|
||||
|
||||
return (
|
||||
<div className="max-w-7xl mx-auto px-6 py-16 space-y-16">
|
||||
<header className="space-y-3">
|
||||
<div className="flex items-center gap-2 text-red-400 text-sm font-bold uppercase tracking-widest">
|
||||
<span className="w-2 h-2 rounded-full bg-red-500 animate-pulse" />
|
||||
{live.length} camera{live.length !== 1 ? 's' : ''} live now
|
||||
</div>
|
||||
<h1 className="text-4xl font-black text-white">Wildlife Cameras</h1>
|
||||
<p className="text-stone-400 text-lg max-w-2xl">
|
||||
Free, 24/7 livestreams from Cape Coral's burrowing owl habitats and wildlife areas.
|
||||
</p>
|
||||
</header>
|
||||
|
||||
{streams.length === 0 && (
|
||||
<div className="flex flex-col items-center justify-center py-32 space-y-4 text-stone-500">
|
||||
<Radio size={48} className="text-stone-600" />
|
||||
<p className="text-lg font-semibold">No cameras available</p>
|
||||
<p className="text-sm">Check back soon or ensure the backend is running.</p>
|
||||
</div>
|
||||
)}
|
||||
|
||||
{live.length > 0 && (
|
||||
<section className="space-y-6">
|
||||
<h2 className="text-xl font-bold text-white flex items-center gap-2">
|
||||
<span className="w-2 h-2 rounded-full bg-red-500 animate-pulse" />
|
||||
Live Now
|
||||
</h2>
|
||||
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6">
|
||||
{live.map((s) => <StreamCard key={s.id} stream={s} />)}
|
||||
</div>
|
||||
</section>
|
||||
)}
|
||||
|
||||
{offline.length > 0 && (
|
||||
<section className="space-y-6">
|
||||
<h2 className="text-xl font-bold text-stone-400">Offline Cameras</h2>
|
||||
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6 opacity-70">
|
||||
{offline.map((s) => <StreamCard key={s.id} stream={s} />)}
|
||||
</div>
|
||||
</section>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
77
app/volunteer/page.tsx
Normal file
77
app/volunteer/page.tsx
Normal file
@ -0,0 +1,77 @@
|
||||
import React from 'react';
|
||||
import { Lock, Users, ClipboardList } from 'lucide-react';
|
||||
import Link from 'next/link';
|
||||
|
||||
export default function VolunteerPage() {
|
||||
return (
|
||||
<div className="max-w-5xl mx-auto px-6 py-16 space-y-12">
|
||||
<header className="space-y-4 max-w-3xl">
|
||||
<div className="flex items-center gap-2 text-teal text-sm font-bold uppercase tracking-widest">
|
||||
<Users size={16} /> Volunteer Portal
|
||||
</div>
|
||||
<h1 className="text-4xl font-black text-white">Join the CCFW Team</h1>
|
||||
<p className="text-stone-400 text-lg leading-relaxed">
|
||||
Our volunteers are the backbone of everything we do. From burrow surveys to habitat restoration, there's a role for everyone.
|
||||
</p>
|
||||
</header>
|
||||
|
||||
{/* Login gate notice */}
|
||||
<div className="bg-surfaceGreen border border-teal/20 rounded-2xl p-8 flex items-start gap-5">
|
||||
<div className="w-12 h-12 rounded-xl bg-teal/10 flex items-center justify-center shrink-0">
|
||||
<Lock size={22} className="text-teal" />
|
||||
</div>
|
||||
<div className="space-y-2">
|
||||
<h3 className="font-bold text-white text-lg">Volunteer Dashboard</h3>
|
||||
<p className="text-stone-400 text-sm leading-relaxed">
|
||||
The full volunteer dashboard (task assignments, hour logging, equipment checkout, and leaderboard) requires a CCFW volunteer account. Log in or register to access.
|
||||
</p>
|
||||
<div className="flex gap-3 pt-2">
|
||||
<Link href="/login" className="px-5 py-2 rounded-lg bg-teal text-white font-bold text-sm hover:bg-tealLight transition-all">
|
||||
Log In
|
||||
</Link>
|
||||
<a href="mailto:info@ccfriendsofwildlife.org" className="px-5 py-2 rounded-lg border border-white/10 text-stone-300 font-bold text-sm hover:bg-white/5 transition-all">
|
||||
Request Access
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Volunteer roles */}
|
||||
<div className="space-y-6">
|
||||
<h2 className="text-2xl font-black text-white">Volunteer Opportunities</h2>
|
||||
<div className="grid grid-cols-1 md:grid-cols-3 gap-5">
|
||||
{[
|
||||
{
|
||||
icon: '🦉',
|
||||
title: 'Owl Surveyor',
|
||||
desc: 'Walk designated survey routes and record burrow activity on a monthly basis.',
|
||||
commitment: '2–4 hrs/month',
|
||||
},
|
||||
{
|
||||
icon: '🌿',
|
||||
title: 'Habitat Restorer',
|
||||
desc: 'Plant native vegetation, remove invasives, and restore critical burrowing owl habitat.',
|
||||
commitment: '4 hrs/quarter',
|
||||
},
|
||||
{
|
||||
icon: '📸',
|
||||
title: 'Camera Monitor',
|
||||
desc: 'Review footage from wildlife cameras, flag notable events, and maintain equipment.',
|
||||
commitment: 'Remote, flexible',
|
||||
},
|
||||
].map(({ icon, title, desc, commitment }) => (
|
||||
<div key={title} className="bg-surfaceGreen border border-white/5 rounded-2xl p-6 space-y-3">
|
||||
<div className="text-4xl">{icon}</div>
|
||||
<h3 className="font-bold text-white text-lg">{title}</h3>
|
||||
<p className="text-stone-400 text-sm leading-relaxed">{desc}</p>
|
||||
<div className="flex items-center gap-2">
|
||||
<ClipboardList size={12} className="text-teal" />
|
||||
<span className="text-xs text-stone-500 font-semibold">{commitment}</span>
|
||||
</div>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
84
app/wildlife/page.tsx
Normal file
84
app/wildlife/page.tsx
Normal file
@ -0,0 +1,84 @@
|
||||
import React from 'react';
|
||||
import { TreePine } from 'lucide-react';
|
||||
import { api, Wildlife } from '@/lib/api';
|
||||
import WildlifeCard from '../components/WildlifeCard';
|
||||
|
||||
// Fallback data when API unavailable
|
||||
const FALLBACK: Wildlife[] = [
|
||||
{
|
||||
id: '1', name: 'Burrowing Owl', scientificName: 'Athene cunicularia',
|
||||
status: 'Threatened',
|
||||
description: 'Cape Coral\'s official city bird. These small ground-dwelling owls nest in burrows, are active during the day, and are a Species of Special Concern in Florida. CCFW monitors thousands of active burrow sites.',
|
||||
habitat: 'Open grasslands, vacant lots, golf courses',
|
||||
},
|
||||
{
|
||||
id: '2', name: 'Gopher Tortoise', scientificName: 'Gopherus polyphemus',
|
||||
status: 'Threatened',
|
||||
description: 'A keystone species whose burrows shelter over 350 other animal species. Their habitat is disappearing rapidly due to development. Florida law protects gopher tortoises and their burrows.',
|
||||
habitat: 'Dry upland habitats, scrub, longleaf pine',
|
||||
},
|
||||
{
|
||||
id: '3', name: 'Florida Scrub-Jay', scientificName: 'Aphelocoma coerulescens',
|
||||
status: 'Threatened',
|
||||
description: 'Florida\'s only endemic bird species, found nowhere else on Earth. These intelligent, cooperative-breeding birds require open, scrubby habitat that has declined by 90% over the past century.',
|
||||
habitat: 'Florida scrub habitat',
|
||||
},
|
||||
{
|
||||
id: '4', name: 'Florida Manatee', scientificName: 'Trichechus manatus latirostris',
|
||||
status: 'Threatened',
|
||||
description: 'Gentle marine mammals that frequent Southwest Florida\'s warm waters. Threats include boat strikes, cold stress, and habitat loss. Cape Coral\'s canals serve as critical manatee habitat.',
|
||||
habitat: 'Coastal waterways, canals, springs',
|
||||
},
|
||||
];
|
||||
|
||||
async function getWildlife(): Promise<Wildlife[]> {
|
||||
try { return await api.getWildlife(); }
|
||||
catch { return FALLBACK; }
|
||||
}
|
||||
|
||||
export default async function WildlifePage() {
|
||||
const species = await getWildlife();
|
||||
|
||||
return (
|
||||
<div className="max-w-7xl mx-auto px-6 py-16 space-y-14">
|
||||
<header className="space-y-4 max-w-3xl">
|
||||
<div className="flex items-center gap-2 text-teal text-sm font-bold uppercase tracking-widest">
|
||||
<TreePine size={16} /> Native Species
|
||||
</div>
|
||||
<h1 className="text-4xl font-black text-white">Southwest Florida Wildlife</h1>
|
||||
<p className="text-stone-400 text-lg leading-relaxed">
|
||||
Cape Coral and Southwest Florida are home to remarkable native species. CCFW works to protect, monitor, and educate the community about these irreplaceable animals.
|
||||
</p>
|
||||
</header>
|
||||
|
||||
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 gap-6">
|
||||
{species.map((s) => <WildlifeCard key={s.id} species={s} />)}
|
||||
</div>
|
||||
|
||||
{/* Conservation info panel */}
|
||||
<div className="bg-surfaceGreen border border-white/5 rounded-3xl p-10 grid grid-cols-1 md:grid-cols-3 gap-8">
|
||||
<div className="md:col-span-2 space-y-4">
|
||||
<h3 className="text-2xl font-black text-white">Why It Matters</h3>
|
||||
<p className="text-stone-400 leading-relaxed">
|
||||
Southwest Florida's rapid growth has put enormous pressure on wildlife habitat. Cape Coral, despite being one of the most densely populated cities in Florida, still harbors significant populations of protected species — but only because of active conservation efforts.
|
||||
</p>
|
||||
<p className="text-stone-400 leading-relaxed">
|
||||
CCFW's work includes burrow monitoring, community education, habitat restoration, and advocacy to ensure these species have a future in Cape Coral.
|
||||
</p>
|
||||
</div>
|
||||
<div className="flex flex-col justify-center gap-6">
|
||||
{[
|
||||
{ num: '2,000+', label: 'Owl burrows monitored' },
|
||||
{ num: '25+', label: 'Years of conservation' },
|
||||
{ num: '100%', label: 'Volunteer powered' },
|
||||
].map(({ num, label }) => (
|
||||
<div key={label} className="text-center">
|
||||
<div className="text-3xl font-black text-gold">{num}</div>
|
||||
<div className="text-xs text-stone-500 font-semibold uppercase tracking-wider mt-1">{label}</div>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
39
backend/Dockerfile
Normal file
39
backend/Dockerfile
Normal file
@ -0,0 +1,39 @@
|
||||
FROM node:20-alpine AS builder
|
||||
|
||||
WORKDIR /app
|
||||
|
||||
COPY package.json package-lock.json* ./
|
||||
RUN npm ci
|
||||
|
||||
COPY tsconfig.json ./
|
||||
COPY prisma ./prisma
|
||||
COPY src ./src
|
||||
|
||||
RUN npx prisma generate
|
||||
RUN npm run build
|
||||
|
||||
# --- Runtime stage ---
|
||||
FROM node:20-alpine AS runner
|
||||
|
||||
# Install OpenSSL libraries required by Prisma
|
||||
RUN apk add --no-cache openssl libssl3
|
||||
|
||||
RUN addgroup --gid 1001 appgroup && \
|
||||
adduser -D -u 1001 -G appgroup appuser
|
||||
|
||||
WORKDIR /app
|
||||
|
||||
COPY package.json package-lock.json* ./
|
||||
RUN npm ci --omit=dev
|
||||
|
||||
COPY --from=builder /app/dist ./dist
|
||||
COPY prisma ./prisma
|
||||
RUN npx prisma generate
|
||||
|
||||
RUN chown -R appuser:appgroup /app
|
||||
|
||||
USER appuser
|
||||
|
||||
EXPOSE 3007
|
||||
|
||||
CMD ["node", "dist/index.js"]
|
||||
1
backend/node_modules/.bin/acorn
generated
vendored
Symbolic link
1
backend/node_modules/.bin/acorn
generated
vendored
Symbolic link
@ -0,0 +1 @@
|
||||
../acorn/bin/acorn
|
||||
1
backend/node_modules/.bin/mime
generated
vendored
Symbolic link
1
backend/node_modules/.bin/mime
generated
vendored
Symbolic link
@ -0,0 +1 @@
|
||||
../mime/cli.js
|
||||
1
backend/node_modules/.bin/mkdirp
generated
vendored
Symbolic link
1
backend/node_modules/.bin/mkdirp
generated
vendored
Symbolic link
@ -0,0 +1 @@
|
||||
../mkdirp/bin/cmd.js
|
||||
1
backend/node_modules/.bin/prisma
generated
vendored
Symbolic link
1
backend/node_modules/.bin/prisma
generated
vendored
Symbolic link
@ -0,0 +1 @@
|
||||
../prisma/build/index.js
|
||||
1
backend/node_modules/.bin/resolve
generated
vendored
Symbolic link
1
backend/node_modules/.bin/resolve
generated
vendored
Symbolic link
@ -0,0 +1 @@
|
||||
../resolve/bin/resolve
|
||||
1
backend/node_modules/.bin/rimraf
generated
vendored
Symbolic link
1
backend/node_modules/.bin/rimraf
generated
vendored
Symbolic link
@ -0,0 +1 @@
|
||||
../rimraf/bin.js
|
||||
1
backend/node_modules/.bin/semver
generated
vendored
Symbolic link
1
backend/node_modules/.bin/semver
generated
vendored
Symbolic link
@ -0,0 +1 @@
|
||||
../semver/bin/semver.js
|
||||
1
backend/node_modules/.bin/tree-kill
generated
vendored
Symbolic link
1
backend/node_modules/.bin/tree-kill
generated
vendored
Symbolic link
@ -0,0 +1 @@
|
||||
../tree-kill/cli.js
|
||||
1
backend/node_modules/.bin/ts-node
generated
vendored
Symbolic link
1
backend/node_modules/.bin/ts-node
generated
vendored
Symbolic link
@ -0,0 +1 @@
|
||||
../ts-node/dist/bin.js
|
||||
1
backend/node_modules/.bin/ts-node-cwd
generated
vendored
Symbolic link
1
backend/node_modules/.bin/ts-node-cwd
generated
vendored
Symbolic link
@ -0,0 +1 @@
|
||||
../ts-node/dist/bin-cwd.js
|
||||
1
backend/node_modules/.bin/ts-node-dev
generated
vendored
Symbolic link
1
backend/node_modules/.bin/ts-node-dev
generated
vendored
Symbolic link
@ -0,0 +1 @@
|
||||
../ts-node-dev/lib/bin.js
|
||||
1
backend/node_modules/.bin/ts-node-esm
generated
vendored
Symbolic link
1
backend/node_modules/.bin/ts-node-esm
generated
vendored
Symbolic link
@ -0,0 +1 @@
|
||||
../ts-node/dist/bin-esm.js
|
||||
1
backend/node_modules/.bin/ts-node-script
generated
vendored
Symbolic link
1
backend/node_modules/.bin/ts-node-script
generated
vendored
Symbolic link
@ -0,0 +1 @@
|
||||
../ts-node/dist/bin-script.js
|
||||
1
backend/node_modules/.bin/ts-node-transpile-only
generated
vendored
Symbolic link
1
backend/node_modules/.bin/ts-node-transpile-only
generated
vendored
Symbolic link
@ -0,0 +1 @@
|
||||
../ts-node/dist/bin-transpile.js
|
||||
1
backend/node_modules/.bin/ts-script
generated
vendored
Symbolic link
1
backend/node_modules/.bin/ts-script
generated
vendored
Symbolic link
@ -0,0 +1 @@
|
||||
../ts-node/dist/bin-script-deprecated.js
|
||||
1
backend/node_modules/.bin/tsc
generated
vendored
Symbolic link
1
backend/node_modules/.bin/tsc
generated
vendored
Symbolic link
@ -0,0 +1 @@
|
||||
../typescript/bin/tsc
|
||||
1
backend/node_modules/.bin/tsnd
generated
vendored
Symbolic link
1
backend/node_modules/.bin/tsnd
generated
vendored
Symbolic link
@ -0,0 +1 @@
|
||||
../ts-node-dev/lib/bin.js
|
||||
1
backend/node_modules/.bin/tsserver
generated
vendored
Symbolic link
1
backend/node_modules/.bin/tsserver
generated
vendored
Symbolic link
@ -0,0 +1 @@
|
||||
../typescript/bin/tsserver
|
||||
1985
backend/node_modules/.package-lock.json
generated
vendored
Normal file
1985
backend/node_modules/.package-lock.json
generated
vendored
Normal file
File diff suppressed because it is too large
Load Diff
1
backend/node_modules/.prisma/client/default.d.ts
generated
vendored
Normal file
1
backend/node_modules/.prisma/client/default.d.ts
generated
vendored
Normal file
@ -0,0 +1 @@
|
||||
export * from "./index"
|
||||
1
backend/node_modules/.prisma/client/default.js
generated
vendored
Normal file
1
backend/node_modules/.prisma/client/default.js
generated
vendored
Normal file
@ -0,0 +1 @@
|
||||
module.exports = { ...require('.') }
|
||||
9
backend/node_modules/.prisma/client/deno/edge.d.ts
generated
vendored
Normal file
9
backend/node_modules/.prisma/client/deno/edge.d.ts
generated
vendored
Normal file
@ -0,0 +1,9 @@
|
||||
class PrismaClient {
|
||||
constructor() {
|
||||
throw new Error(
|
||||
'@prisma/client/deno/edge did not initialize yet. Please run "prisma generate" and try to import it again.',
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
export { PrismaClient }
|
||||
1
backend/node_modules/.prisma/client/edge.d.ts
generated
vendored
Normal file
1
backend/node_modules/.prisma/client/edge.d.ts
generated
vendored
Normal file
@ -0,0 +1 @@
|
||||
export * from "./default"
|
||||
310
backend/node_modules/.prisma/client/edge.js
generated
vendored
Normal file
310
backend/node_modules/.prisma/client/edge.js
generated
vendored
Normal file
File diff suppressed because one or more lines are too long
303
backend/node_modules/.prisma/client/index-browser.js
generated
vendored
Normal file
303
backend/node_modules/.prisma/client/index-browser.js
generated
vendored
Normal file
@ -0,0 +1,303 @@
|
||||
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
|
||||
const {
|
||||
Decimal,
|
||||
objectEnumValues,
|
||||
makeStrictEnum,
|
||||
Public,
|
||||
getRuntime,
|
||||
skip
|
||||
} = require('@prisma/client/runtime/index-browser.js')
|
||||
|
||||
|
||||
const Prisma = {}
|
||||
|
||||
exports.Prisma = Prisma
|
||||
exports.$Enums = {}
|
||||
|
||||
/**
|
||||
* Prisma Client JS version: 5.22.0
|
||||
* Query Engine version: 605197351a3c8bdd595af2d2a9bc3025bca48ea2
|
||||
*/
|
||||
Prisma.prismaVersion = {
|
||||
client: "5.22.0",
|
||||
engine: "605197351a3c8bdd595af2d2a9bc3025bca48ea2"
|
||||
}
|
||||
|
||||
Prisma.PrismaClientKnownRequestError = () => {
|
||||
const runtimeName = getRuntime().prettyName;
|
||||
throw new Error(`PrismaClientKnownRequestError is unable to run in this browser environment, or has been bundled for the browser (running in ${runtimeName}).
|
||||
In case this error is unexpected for you, please report it in https://pris.ly/prisma-prisma-bug-report`,
|
||||
)};
|
||||
Prisma.PrismaClientUnknownRequestError = () => {
|
||||
const runtimeName = getRuntime().prettyName;
|
||||
throw new Error(`PrismaClientUnknownRequestError is unable to run in this browser environment, or has been bundled for the browser (running in ${runtimeName}).
|
||||
In case this error is unexpected for you, please report it in https://pris.ly/prisma-prisma-bug-report`,
|
||||
)}
|
||||
Prisma.PrismaClientRustPanicError = () => {
|
||||
const runtimeName = getRuntime().prettyName;
|
||||
throw new Error(`PrismaClientRustPanicError is unable to run in this browser environment, or has been bundled for the browser (running in ${runtimeName}).
|
||||
In case this error is unexpected for you, please report it in https://pris.ly/prisma-prisma-bug-report`,
|
||||
)}
|
||||
Prisma.PrismaClientInitializationError = () => {
|
||||
const runtimeName = getRuntime().prettyName;
|
||||
throw new Error(`PrismaClientInitializationError is unable to run in this browser environment, or has been bundled for the browser (running in ${runtimeName}).
|
||||
In case this error is unexpected for you, please report it in https://pris.ly/prisma-prisma-bug-report`,
|
||||
)}
|
||||
Prisma.PrismaClientValidationError = () => {
|
||||
const runtimeName = getRuntime().prettyName;
|
||||
throw new Error(`PrismaClientValidationError is unable to run in this browser environment, or has been bundled for the browser (running in ${runtimeName}).
|
||||
In case this error is unexpected for you, please report it in https://pris.ly/prisma-prisma-bug-report`,
|
||||
)}
|
||||
Prisma.NotFoundError = () => {
|
||||
const runtimeName = getRuntime().prettyName;
|
||||
throw new Error(`NotFoundError is unable to run in this browser environment, or has been bundled for the browser (running in ${runtimeName}).
|
||||
In case this error is unexpected for you, please report it in https://pris.ly/prisma-prisma-bug-report`,
|
||||
)}
|
||||
Prisma.Decimal = Decimal
|
||||
|
||||
/**
|
||||
* Re-export of sql-template-tag
|
||||
*/
|
||||
Prisma.sql = () => {
|
||||
const runtimeName = getRuntime().prettyName;
|
||||
throw new Error(`sqltag is unable to run in this browser environment, or has been bundled for the browser (running in ${runtimeName}).
|
||||
In case this error is unexpected for you, please report it in https://pris.ly/prisma-prisma-bug-report`,
|
||||
)}
|
||||
Prisma.empty = () => {
|
||||
const runtimeName = getRuntime().prettyName;
|
||||
throw new Error(`empty is unable to run in this browser environment, or has been bundled for the browser (running in ${runtimeName}).
|
||||
In case this error is unexpected for you, please report it in https://pris.ly/prisma-prisma-bug-report`,
|
||||
)}
|
||||
Prisma.join = () => {
|
||||
const runtimeName = getRuntime().prettyName;
|
||||
throw new Error(`join is unable to run in this browser environment, or has been bundled for the browser (running in ${runtimeName}).
|
||||
In case this error is unexpected for you, please report it in https://pris.ly/prisma-prisma-bug-report`,
|
||||
)}
|
||||
Prisma.raw = () => {
|
||||
const runtimeName = getRuntime().prettyName;
|
||||
throw new Error(`raw is unable to run in this browser environment, or has been bundled for the browser (running in ${runtimeName}).
|
||||
In case this error is unexpected for you, please report it in https://pris.ly/prisma-prisma-bug-report`,
|
||||
)}
|
||||
Prisma.validator = Public.validator
|
||||
|
||||
/**
|
||||
* Extensions
|
||||
*/
|
||||
Prisma.getExtensionContext = () => {
|
||||
const runtimeName = getRuntime().prettyName;
|
||||
throw new Error(`Extensions.getExtensionContext is unable to run in this browser environment, or has been bundled for the browser (running in ${runtimeName}).
|
||||
In case this error is unexpected for you, please report it in https://pris.ly/prisma-prisma-bug-report`,
|
||||
)}
|
||||
Prisma.defineExtension = () => {
|
||||
const runtimeName = getRuntime().prettyName;
|
||||
throw new Error(`Extensions.defineExtension is unable to run in this browser environment, or has been bundled for the browser (running in ${runtimeName}).
|
||||
In case this error is unexpected for you, please report it in https://pris.ly/prisma-prisma-bug-report`,
|
||||
)}
|
||||
|
||||
/**
|
||||
* Shorthand utilities for JSON filtering
|
||||
*/
|
||||
Prisma.DbNull = objectEnumValues.instances.DbNull
|
||||
Prisma.JsonNull = objectEnumValues.instances.JsonNull
|
||||
Prisma.AnyNull = objectEnumValues.instances.AnyNull
|
||||
|
||||
Prisma.NullTypes = {
|
||||
DbNull: objectEnumValues.classes.DbNull,
|
||||
JsonNull: objectEnumValues.classes.JsonNull,
|
||||
AnyNull: objectEnumValues.classes.AnyNull
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Enums
|
||||
*/
|
||||
|
||||
exports.Prisma.TransactionIsolationLevel = makeStrictEnum({
|
||||
ReadUncommitted: 'ReadUncommitted',
|
||||
ReadCommitted: 'ReadCommitted',
|
||||
RepeatableRead: 'RepeatableRead',
|
||||
Serializable: 'Serializable'
|
||||
});
|
||||
|
||||
exports.Prisma.UserScalarFieldEnum = {
|
||||
id: 'id',
|
||||
email: 'email',
|
||||
name: 'name',
|
||||
role: 'role',
|
||||
password_hash: 'password_hash',
|
||||
created_at: 'created_at'
|
||||
};
|
||||
|
||||
exports.Prisma.BurrowScalarFieldEnum = {
|
||||
id: 'id',
|
||||
gps_lat: 'gps_lat',
|
||||
gps_lng: 'gps_lng',
|
||||
status: 'status',
|
||||
location_description: 'location_description',
|
||||
photos: 'photos',
|
||||
assigned_volunteer_id: 'assigned_volunteer_id',
|
||||
created_at: 'created_at'
|
||||
};
|
||||
|
||||
exports.Prisma.DonationScalarFieldEnum = {
|
||||
id: 'id',
|
||||
donor_id: 'donor_id',
|
||||
amount: 'amount',
|
||||
campaign: 'campaign',
|
||||
stripe_payment_id: 'stripe_payment_id',
|
||||
created_at: 'created_at'
|
||||
};
|
||||
|
||||
exports.Prisma.WildlifeSightingScalarFieldEnum = {
|
||||
id: 'id',
|
||||
reporter_id: 'reporter_id',
|
||||
species: 'species',
|
||||
gps_lat: 'gps_lat',
|
||||
gps_lng: 'gps_lng',
|
||||
photo_url: 'photo_url',
|
||||
description: 'description',
|
||||
verified: 'verified',
|
||||
created_at: 'created_at'
|
||||
};
|
||||
|
||||
exports.Prisma.EventScalarFieldEnum = {
|
||||
id: 'id',
|
||||
title: 'title',
|
||||
description: 'description',
|
||||
date: 'date',
|
||||
location: 'location',
|
||||
max_attendees: 'max_attendees',
|
||||
type: 'type',
|
||||
created_at: 'created_at'
|
||||
};
|
||||
|
||||
exports.Prisma.EventRSVPScalarFieldEnum = {
|
||||
event_id: 'event_id',
|
||||
user_id: 'user_id',
|
||||
created_at: 'created_at'
|
||||
};
|
||||
|
||||
exports.Prisma.LivestreamSourceScalarFieldEnum = {
|
||||
id: 'id',
|
||||
name: 'name',
|
||||
stream_url: 'stream_url',
|
||||
camera_location: 'camera_location',
|
||||
status: 'status',
|
||||
thumbnail_url: 'thumbnail_url',
|
||||
created_at: 'created_at'
|
||||
};
|
||||
|
||||
exports.Prisma.VolunteerHourScalarFieldEnum = {
|
||||
id: 'id',
|
||||
volunteer_id: 'volunteer_id',
|
||||
date: 'date',
|
||||
hours: 'hours',
|
||||
task_description: 'task_description',
|
||||
verified_by: 'verified_by',
|
||||
created_at: 'created_at'
|
||||
};
|
||||
|
||||
exports.Prisma.EquipmentItemScalarFieldEnum = {
|
||||
id: 'id',
|
||||
name: 'name',
|
||||
description: 'description',
|
||||
status: 'status',
|
||||
checked_out_by: 'checked_out_by',
|
||||
checked_out_at: 'checked_out_at',
|
||||
created_at: 'created_at'
|
||||
};
|
||||
|
||||
exports.Prisma.SortOrder = {
|
||||
asc: 'asc',
|
||||
desc: 'desc'
|
||||
};
|
||||
|
||||
exports.Prisma.QueryMode = {
|
||||
default: 'default',
|
||||
insensitive: 'insensitive'
|
||||
};
|
||||
|
||||
exports.Prisma.NullsOrder = {
|
||||
first: 'first',
|
||||
last: 'last'
|
||||
};
|
||||
exports.UserRole = exports.$Enums.UserRole = {
|
||||
admin: 'admin',
|
||||
volunteer: 'volunteer',
|
||||
donor: 'donor',
|
||||
public: 'public'
|
||||
};
|
||||
|
||||
exports.BurrowStatus = exports.$Enums.BurrowStatus = {
|
||||
active: 'active',
|
||||
inactive: 'inactive',
|
||||
destroyed: 'destroyed'
|
||||
};
|
||||
|
||||
exports.DonationCampaign = exports.$Enums.DonationCampaign = {
|
||||
land_preservation: 'land_preservation',
|
||||
volunteer_equipment: 'volunteer_equipment',
|
||||
general: 'general'
|
||||
};
|
||||
|
||||
exports.EventType = exports.$Enums.EventType = {
|
||||
cleanup: 'cleanup',
|
||||
educational: 'educational',
|
||||
fundraiser: 'fundraiser'
|
||||
};
|
||||
|
||||
exports.StreamStatus = exports.$Enums.StreamStatus = {
|
||||
live: 'live',
|
||||
offline: 'offline'
|
||||
};
|
||||
|
||||
exports.EquipmentStatus = exports.$Enums.EquipmentStatus = {
|
||||
available: 'available',
|
||||
checked_out: 'checked_out'
|
||||
};
|
||||
|
||||
exports.Prisma.ModelName = {
|
||||
User: 'User',
|
||||
Burrow: 'Burrow',
|
||||
Donation: 'Donation',
|
||||
WildlifeSighting: 'WildlifeSighting',
|
||||
Event: 'Event',
|
||||
EventRSVP: 'EventRSVP',
|
||||
LivestreamSource: 'LivestreamSource',
|
||||
VolunteerHour: 'VolunteerHour',
|
||||
EquipmentItem: 'EquipmentItem'
|
||||
};
|
||||
|
||||
/**
|
||||
* This is a stub Prisma Client that will error at runtime if called.
|
||||
*/
|
||||
class PrismaClient {
|
||||
constructor() {
|
||||
return new Proxy(this, {
|
||||
get(target, prop) {
|
||||
let message
|
||||
const runtime = getRuntime()
|
||||
if (runtime.isEdge) {
|
||||
message = `PrismaClient is not configured to run in ${runtime.prettyName}. In order to run Prisma Client on edge runtime, either:
|
||||
- Use Prisma Accelerate: https://pris.ly/d/accelerate
|
||||
- Use Driver Adapters: https://pris.ly/d/driver-adapters
|
||||
`;
|
||||
} else {
|
||||
message = 'PrismaClient is unable to run in this browser environment, or has been bundled for the browser (running in `' + runtime.prettyName + '`).'
|
||||
}
|
||||
|
||||
message += `
|
||||
If this is unexpected, please open an issue: https://pris.ly/prisma-prisma-bug-report`
|
||||
|
||||
throw new Error(message)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
exports.PrismaClient = PrismaClient
|
||||
|
||||
Object.assign(exports, Prisma)
|
||||
15103
backend/node_modules/.prisma/client/index.d.ts
generated
vendored
Normal file
15103
backend/node_modules/.prisma/client/index.d.ts
generated
vendored
Normal file
File diff suppressed because it is too large
Load Diff
331
backend/node_modules/.prisma/client/index.js
generated
vendored
Normal file
331
backend/node_modules/.prisma/client/index.js
generated
vendored
Normal file
File diff suppressed because one or more lines are too long
BIN
backend/node_modules/.prisma/client/libquery_engine-debian-openssl-3.0.x.so.node
generated
vendored
Executable file
BIN
backend/node_modules/.prisma/client/libquery_engine-debian-openssl-3.0.x.so.node
generated
vendored
Executable file
Binary file not shown.
97
backend/node_modules/.prisma/client/package.json
generated
vendored
Normal file
97
backend/node_modules/.prisma/client/package.json
generated
vendored
Normal file
@ -0,0 +1,97 @@
|
||||
{
|
||||
"name": "prisma-client-249312ccdf6fbda509f1ee88be4e8f4171687091556513dc44a1589fe5bc12fe",
|
||||
"main": "index.js",
|
||||
"types": "index.d.ts",
|
||||
"browser": "index-browser.js",
|
||||
"exports": {
|
||||
"./package.json": "./package.json",
|
||||
".": {
|
||||
"require": {
|
||||
"node": "./index.js",
|
||||
"edge-light": "./wasm.js",
|
||||
"workerd": "./wasm.js",
|
||||
"worker": "./wasm.js",
|
||||
"browser": "./index-browser.js",
|
||||
"default": "./index.js"
|
||||
},
|
||||
"import": {
|
||||
"node": "./index.js",
|
||||
"edge-light": "./wasm.js",
|
||||
"workerd": "./wasm.js",
|
||||
"worker": "./wasm.js",
|
||||
"browser": "./index-browser.js",
|
||||
"default": "./index.js"
|
||||
},
|
||||
"default": "./index.js"
|
||||
},
|
||||
"./edge": {
|
||||
"types": "./edge.d.ts",
|
||||
"require": "./edge.js",
|
||||
"import": "./edge.js",
|
||||
"default": "./edge.js"
|
||||
},
|
||||
"./react-native": {
|
||||
"types": "./react-native.d.ts",
|
||||
"require": "./react-native.js",
|
||||
"import": "./react-native.js",
|
||||
"default": "./react-native.js"
|
||||
},
|
||||
"./extension": {
|
||||
"types": "./extension.d.ts",
|
||||
"require": "./extension.js",
|
||||
"import": "./extension.js",
|
||||
"default": "./extension.js"
|
||||
},
|
||||
"./index-browser": {
|
||||
"types": "./index.d.ts",
|
||||
"require": "./index-browser.js",
|
||||
"import": "./index-browser.js",
|
||||
"default": "./index-browser.js"
|
||||
},
|
||||
"./index": {
|
||||
"types": "./index.d.ts",
|
||||
"require": "./index.js",
|
||||
"import": "./index.js",
|
||||
"default": "./index.js"
|
||||
},
|
||||
"./wasm": {
|
||||
"types": "./wasm.d.ts",
|
||||
"require": "./wasm.js",
|
||||
"import": "./wasm.js",
|
||||
"default": "./wasm.js"
|
||||
},
|
||||
"./runtime/library": {
|
||||
"types": "./runtime/library.d.ts",
|
||||
"require": "./runtime/library.js",
|
||||
"import": "./runtime/library.js",
|
||||
"default": "./runtime/library.js"
|
||||
},
|
||||
"./runtime/binary": {
|
||||
"types": "./runtime/binary.d.ts",
|
||||
"require": "./runtime/binary.js",
|
||||
"import": "./runtime/binary.js",
|
||||
"default": "./runtime/binary.js"
|
||||
},
|
||||
"./generator-build": {
|
||||
"require": "./generator-build/index.js",
|
||||
"import": "./generator-build/index.js",
|
||||
"default": "./generator-build/index.js"
|
||||
},
|
||||
"./sql": {
|
||||
"require": {
|
||||
"types": "./sql.d.ts",
|
||||
"node": "./sql.js",
|
||||
"default": "./sql.js"
|
||||
},
|
||||
"import": {
|
||||
"types": "./sql.d.ts",
|
||||
"node": "./sql.mjs",
|
||||
"default": "./sql.mjs"
|
||||
},
|
||||
"default": "./sql.js"
|
||||
},
|
||||
"./*": "./*"
|
||||
},
|
||||
"version": "5.22.0",
|
||||
"sideEffects": false
|
||||
}
|
||||
174
backend/node_modules/.prisma/client/schema.prisma
generated
vendored
Normal file
174
backend/node_modules/.prisma/client/schema.prisma
generated
vendored
Normal file
@ -0,0 +1,174 @@
|
||||
generator client {
|
||||
provider = "prisma-client-js"
|
||||
}
|
||||
|
||||
datasource db {
|
||||
provider = "postgresql"
|
||||
url = env("DATABASE_URL")
|
||||
}
|
||||
|
||||
enum UserRole {
|
||||
admin
|
||||
volunteer
|
||||
donor
|
||||
public
|
||||
}
|
||||
|
||||
enum BurrowStatus {
|
||||
active
|
||||
inactive
|
||||
destroyed
|
||||
}
|
||||
|
||||
enum DonationCampaign {
|
||||
land_preservation
|
||||
volunteer_equipment
|
||||
general
|
||||
}
|
||||
|
||||
enum EventType {
|
||||
cleanup
|
||||
educational
|
||||
fundraiser
|
||||
}
|
||||
|
||||
enum StreamStatus {
|
||||
live
|
||||
offline
|
||||
}
|
||||
|
||||
enum EquipmentStatus {
|
||||
available
|
||||
checked_out
|
||||
}
|
||||
|
||||
model User {
|
||||
id String @id @default(cuid())
|
||||
email String @unique
|
||||
name String
|
||||
role UserRole @default(public)
|
||||
password_hash String
|
||||
created_at DateTime @default(now())
|
||||
|
||||
burrows Burrow[] @relation("AssignedVolunteer")
|
||||
donations Donation[]
|
||||
sightings WildlifeSighting[] @relation("SightingReporter")
|
||||
event_rsvps EventRSVP[]
|
||||
volunteer_hours VolunteerHour[]
|
||||
equipment_items EquipmentItem[] @relation("CheckedOutBy")
|
||||
verified_hours VolunteerHour[] @relation("VerifiedBy")
|
||||
|
||||
@@map("users")
|
||||
}
|
||||
|
||||
model Burrow {
|
||||
id String @id @default(cuid())
|
||||
gps_lat Float
|
||||
gps_lng Float
|
||||
status BurrowStatus @default(active)
|
||||
location_description String?
|
||||
photos String[] @default([])
|
||||
assigned_volunteer_id String?
|
||||
created_at DateTime @default(now())
|
||||
|
||||
assigned_volunteer User? @relation("AssignedVolunteer", fields: [assigned_volunteer_id], references: [id], onDelete: SetNull)
|
||||
|
||||
@@map("burrows")
|
||||
}
|
||||
|
||||
model Donation {
|
||||
id String @id @default(cuid())
|
||||
donor_id String?
|
||||
amount Float
|
||||
campaign DonationCampaign @default(general)
|
||||
stripe_payment_id String?
|
||||
created_at DateTime @default(now())
|
||||
|
||||
donor User? @relation(fields: [donor_id], references: [id], onDelete: SetNull)
|
||||
|
||||
@@map("donations")
|
||||
}
|
||||
|
||||
model WildlifeSighting {
|
||||
id String @id @default(cuid())
|
||||
reporter_id String?
|
||||
species String
|
||||
gps_lat Float
|
||||
gps_lng Float
|
||||
photo_url String?
|
||||
description String?
|
||||
verified Boolean @default(false)
|
||||
created_at DateTime @default(now())
|
||||
|
||||
reporter User? @relation("SightingReporter", fields: [reporter_id], references: [id], onDelete: SetNull)
|
||||
|
||||
@@map("wildlife_sightings")
|
||||
}
|
||||
|
||||
model Event {
|
||||
id String @id @default(cuid())
|
||||
title String
|
||||
description String?
|
||||
date DateTime
|
||||
location String
|
||||
max_attendees Int?
|
||||
type EventType
|
||||
created_at DateTime @default(now())
|
||||
|
||||
rsvps EventRSVP[]
|
||||
|
||||
@@map("events")
|
||||
}
|
||||
|
||||
model EventRSVP {
|
||||
event_id String
|
||||
user_id String
|
||||
created_at DateTime @default(now())
|
||||
|
||||
event Event @relation(fields: [event_id], references: [id], onDelete: Cascade)
|
||||
user User @relation(fields: [user_id], references: [id], onDelete: Cascade)
|
||||
|
||||
@@id([event_id, user_id])
|
||||
@@map("event_rsvps")
|
||||
}
|
||||
|
||||
model LivestreamSource {
|
||||
id String @id @default(cuid())
|
||||
name String
|
||||
stream_url String
|
||||
camera_location String
|
||||
status StreamStatus @default(offline)
|
||||
thumbnail_url String?
|
||||
created_at DateTime @default(now())
|
||||
|
||||
@@map("livestream_sources")
|
||||
}
|
||||
|
||||
model VolunteerHour {
|
||||
id String @id @default(cuid())
|
||||
volunteer_id String
|
||||
date DateTime
|
||||
hours Float
|
||||
task_description String
|
||||
verified_by String?
|
||||
created_at DateTime @default(now())
|
||||
|
||||
volunteer User @relation(fields: [volunteer_id], references: [id], onDelete: Cascade)
|
||||
verifier User? @relation("VerifiedBy", fields: [verified_by], references: [id], onDelete: SetNull)
|
||||
|
||||
@@map("volunteer_hours")
|
||||
}
|
||||
|
||||
model EquipmentItem {
|
||||
id String @id @default(cuid())
|
||||
name String
|
||||
description String?
|
||||
status EquipmentStatus @default(available)
|
||||
checked_out_by String?
|
||||
checked_out_at DateTime?
|
||||
created_at DateTime @default(now())
|
||||
|
||||
checker User? @relation("CheckedOutBy", fields: [checked_out_by], references: [id], onDelete: SetNull)
|
||||
|
||||
@@map("equipment_items")
|
||||
}
|
||||
1
backend/node_modules/.prisma/client/wasm.d.ts
generated
vendored
Normal file
1
backend/node_modules/.prisma/client/wasm.d.ts
generated
vendored
Normal file
@ -0,0 +1 @@
|
||||
export * from "./index"
|
||||
303
backend/node_modules/.prisma/client/wasm.js
generated
vendored
Normal file
303
backend/node_modules/.prisma/client/wasm.js
generated
vendored
Normal file
@ -0,0 +1,303 @@
|
||||
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
|
||||
const {
|
||||
Decimal,
|
||||
objectEnumValues,
|
||||
makeStrictEnum,
|
||||
Public,
|
||||
getRuntime,
|
||||
skip
|
||||
} = require('@prisma/client/runtime/index-browser.js')
|
||||
|
||||
|
||||
const Prisma = {}
|
||||
|
||||
exports.Prisma = Prisma
|
||||
exports.$Enums = {}
|
||||
|
||||
/**
|
||||
* Prisma Client JS version: 5.22.0
|
||||
* Query Engine version: 605197351a3c8bdd595af2d2a9bc3025bca48ea2
|
||||
*/
|
||||
Prisma.prismaVersion = {
|
||||
client: "5.22.0",
|
||||
engine: "605197351a3c8bdd595af2d2a9bc3025bca48ea2"
|
||||
}
|
||||
|
||||
Prisma.PrismaClientKnownRequestError = () => {
|
||||
const runtimeName = getRuntime().prettyName;
|
||||
throw new Error(`PrismaClientKnownRequestError is unable to run in this browser environment, or has been bundled for the browser (running in ${runtimeName}).
|
||||
In case this error is unexpected for you, please report it in https://pris.ly/prisma-prisma-bug-report`,
|
||||
)};
|
||||
Prisma.PrismaClientUnknownRequestError = () => {
|
||||
const runtimeName = getRuntime().prettyName;
|
||||
throw new Error(`PrismaClientUnknownRequestError is unable to run in this browser environment, or has been bundled for the browser (running in ${runtimeName}).
|
||||
In case this error is unexpected for you, please report it in https://pris.ly/prisma-prisma-bug-report`,
|
||||
)}
|
||||
Prisma.PrismaClientRustPanicError = () => {
|
||||
const runtimeName = getRuntime().prettyName;
|
||||
throw new Error(`PrismaClientRustPanicError is unable to run in this browser environment, or has been bundled for the browser (running in ${runtimeName}).
|
||||
In case this error is unexpected for you, please report it in https://pris.ly/prisma-prisma-bug-report`,
|
||||
)}
|
||||
Prisma.PrismaClientInitializationError = () => {
|
||||
const runtimeName = getRuntime().prettyName;
|
||||
throw new Error(`PrismaClientInitializationError is unable to run in this browser environment, or has been bundled for the browser (running in ${runtimeName}).
|
||||
In case this error is unexpected for you, please report it in https://pris.ly/prisma-prisma-bug-report`,
|
||||
)}
|
||||
Prisma.PrismaClientValidationError = () => {
|
||||
const runtimeName = getRuntime().prettyName;
|
||||
throw new Error(`PrismaClientValidationError is unable to run in this browser environment, or has been bundled for the browser (running in ${runtimeName}).
|
||||
In case this error is unexpected for you, please report it in https://pris.ly/prisma-prisma-bug-report`,
|
||||
)}
|
||||
Prisma.NotFoundError = () => {
|
||||
const runtimeName = getRuntime().prettyName;
|
||||
throw new Error(`NotFoundError is unable to run in this browser environment, or has been bundled for the browser (running in ${runtimeName}).
|
||||
In case this error is unexpected for you, please report it in https://pris.ly/prisma-prisma-bug-report`,
|
||||
)}
|
||||
Prisma.Decimal = Decimal
|
||||
|
||||
/**
|
||||
* Re-export of sql-template-tag
|
||||
*/
|
||||
Prisma.sql = () => {
|
||||
const runtimeName = getRuntime().prettyName;
|
||||
throw new Error(`sqltag is unable to run in this browser environment, or has been bundled for the browser (running in ${runtimeName}).
|
||||
In case this error is unexpected for you, please report it in https://pris.ly/prisma-prisma-bug-report`,
|
||||
)}
|
||||
Prisma.empty = () => {
|
||||
const runtimeName = getRuntime().prettyName;
|
||||
throw new Error(`empty is unable to run in this browser environment, or has been bundled for the browser (running in ${runtimeName}).
|
||||
In case this error is unexpected for you, please report it in https://pris.ly/prisma-prisma-bug-report`,
|
||||
)}
|
||||
Prisma.join = () => {
|
||||
const runtimeName = getRuntime().prettyName;
|
||||
throw new Error(`join is unable to run in this browser environment, or has been bundled for the browser (running in ${runtimeName}).
|
||||
In case this error is unexpected for you, please report it in https://pris.ly/prisma-prisma-bug-report`,
|
||||
)}
|
||||
Prisma.raw = () => {
|
||||
const runtimeName = getRuntime().prettyName;
|
||||
throw new Error(`raw is unable to run in this browser environment, or has been bundled for the browser (running in ${runtimeName}).
|
||||
In case this error is unexpected for you, please report it in https://pris.ly/prisma-prisma-bug-report`,
|
||||
)}
|
||||
Prisma.validator = Public.validator
|
||||
|
||||
/**
|
||||
* Extensions
|
||||
*/
|
||||
Prisma.getExtensionContext = () => {
|
||||
const runtimeName = getRuntime().prettyName;
|
||||
throw new Error(`Extensions.getExtensionContext is unable to run in this browser environment, or has been bundled for the browser (running in ${runtimeName}).
|
||||
In case this error is unexpected for you, please report it in https://pris.ly/prisma-prisma-bug-report`,
|
||||
)}
|
||||
Prisma.defineExtension = () => {
|
||||
const runtimeName = getRuntime().prettyName;
|
||||
throw new Error(`Extensions.defineExtension is unable to run in this browser environment, or has been bundled for the browser (running in ${runtimeName}).
|
||||
In case this error is unexpected for you, please report it in https://pris.ly/prisma-prisma-bug-report`,
|
||||
)}
|
||||
|
||||
/**
|
||||
* Shorthand utilities for JSON filtering
|
||||
*/
|
||||
Prisma.DbNull = objectEnumValues.instances.DbNull
|
||||
Prisma.JsonNull = objectEnumValues.instances.JsonNull
|
||||
Prisma.AnyNull = objectEnumValues.instances.AnyNull
|
||||
|
||||
Prisma.NullTypes = {
|
||||
DbNull: objectEnumValues.classes.DbNull,
|
||||
JsonNull: objectEnumValues.classes.JsonNull,
|
||||
AnyNull: objectEnumValues.classes.AnyNull
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Enums
|
||||
*/
|
||||
|
||||
exports.Prisma.TransactionIsolationLevel = makeStrictEnum({
|
||||
ReadUncommitted: 'ReadUncommitted',
|
||||
ReadCommitted: 'ReadCommitted',
|
||||
RepeatableRead: 'RepeatableRead',
|
||||
Serializable: 'Serializable'
|
||||
});
|
||||
|
||||
exports.Prisma.UserScalarFieldEnum = {
|
||||
id: 'id',
|
||||
email: 'email',
|
||||
name: 'name',
|
||||
role: 'role',
|
||||
password_hash: 'password_hash',
|
||||
created_at: 'created_at'
|
||||
};
|
||||
|
||||
exports.Prisma.BurrowScalarFieldEnum = {
|
||||
id: 'id',
|
||||
gps_lat: 'gps_lat',
|
||||
gps_lng: 'gps_lng',
|
||||
status: 'status',
|
||||
location_description: 'location_description',
|
||||
photos: 'photos',
|
||||
assigned_volunteer_id: 'assigned_volunteer_id',
|
||||
created_at: 'created_at'
|
||||
};
|
||||
|
||||
exports.Prisma.DonationScalarFieldEnum = {
|
||||
id: 'id',
|
||||
donor_id: 'donor_id',
|
||||
amount: 'amount',
|
||||
campaign: 'campaign',
|
||||
stripe_payment_id: 'stripe_payment_id',
|
||||
created_at: 'created_at'
|
||||
};
|
||||
|
||||
exports.Prisma.WildlifeSightingScalarFieldEnum = {
|
||||
id: 'id',
|
||||
reporter_id: 'reporter_id',
|
||||
species: 'species',
|
||||
gps_lat: 'gps_lat',
|
||||
gps_lng: 'gps_lng',
|
||||
photo_url: 'photo_url',
|
||||
description: 'description',
|
||||
verified: 'verified',
|
||||
created_at: 'created_at'
|
||||
};
|
||||
|
||||
exports.Prisma.EventScalarFieldEnum = {
|
||||
id: 'id',
|
||||
title: 'title',
|
||||
description: 'description',
|
||||
date: 'date',
|
||||
location: 'location',
|
||||
max_attendees: 'max_attendees',
|
||||
type: 'type',
|
||||
created_at: 'created_at'
|
||||
};
|
||||
|
||||
exports.Prisma.EventRSVPScalarFieldEnum = {
|
||||
event_id: 'event_id',
|
||||
user_id: 'user_id',
|
||||
created_at: 'created_at'
|
||||
};
|
||||
|
||||
exports.Prisma.LivestreamSourceScalarFieldEnum = {
|
||||
id: 'id',
|
||||
name: 'name',
|
||||
stream_url: 'stream_url',
|
||||
camera_location: 'camera_location',
|
||||
status: 'status',
|
||||
thumbnail_url: 'thumbnail_url',
|
||||
created_at: 'created_at'
|
||||
};
|
||||
|
||||
exports.Prisma.VolunteerHourScalarFieldEnum = {
|
||||
id: 'id',
|
||||
volunteer_id: 'volunteer_id',
|
||||
date: 'date',
|
||||
hours: 'hours',
|
||||
task_description: 'task_description',
|
||||
verified_by: 'verified_by',
|
||||
created_at: 'created_at'
|
||||
};
|
||||
|
||||
exports.Prisma.EquipmentItemScalarFieldEnum = {
|
||||
id: 'id',
|
||||
name: 'name',
|
||||
description: 'description',
|
||||
status: 'status',
|
||||
checked_out_by: 'checked_out_by',
|
||||
checked_out_at: 'checked_out_at',
|
||||
created_at: 'created_at'
|
||||
};
|
||||
|
||||
exports.Prisma.SortOrder = {
|
||||
asc: 'asc',
|
||||
desc: 'desc'
|
||||
};
|
||||
|
||||
exports.Prisma.QueryMode = {
|
||||
default: 'default',
|
||||
insensitive: 'insensitive'
|
||||
};
|
||||
|
||||
exports.Prisma.NullsOrder = {
|
||||
first: 'first',
|
||||
last: 'last'
|
||||
};
|
||||
exports.UserRole = exports.$Enums.UserRole = {
|
||||
admin: 'admin',
|
||||
volunteer: 'volunteer',
|
||||
donor: 'donor',
|
||||
public: 'public'
|
||||
};
|
||||
|
||||
exports.BurrowStatus = exports.$Enums.BurrowStatus = {
|
||||
active: 'active',
|
||||
inactive: 'inactive',
|
||||
destroyed: 'destroyed'
|
||||
};
|
||||
|
||||
exports.DonationCampaign = exports.$Enums.DonationCampaign = {
|
||||
land_preservation: 'land_preservation',
|
||||
volunteer_equipment: 'volunteer_equipment',
|
||||
general: 'general'
|
||||
};
|
||||
|
||||
exports.EventType = exports.$Enums.EventType = {
|
||||
cleanup: 'cleanup',
|
||||
educational: 'educational',
|
||||
fundraiser: 'fundraiser'
|
||||
};
|
||||
|
||||
exports.StreamStatus = exports.$Enums.StreamStatus = {
|
||||
live: 'live',
|
||||
offline: 'offline'
|
||||
};
|
||||
|
||||
exports.EquipmentStatus = exports.$Enums.EquipmentStatus = {
|
||||
available: 'available',
|
||||
checked_out: 'checked_out'
|
||||
};
|
||||
|
||||
exports.Prisma.ModelName = {
|
||||
User: 'User',
|
||||
Burrow: 'Burrow',
|
||||
Donation: 'Donation',
|
||||
WildlifeSighting: 'WildlifeSighting',
|
||||
Event: 'Event',
|
||||
EventRSVP: 'EventRSVP',
|
||||
LivestreamSource: 'LivestreamSource',
|
||||
VolunteerHour: 'VolunteerHour',
|
||||
EquipmentItem: 'EquipmentItem'
|
||||
};
|
||||
|
||||
/**
|
||||
* This is a stub Prisma Client that will error at runtime if called.
|
||||
*/
|
||||
class PrismaClient {
|
||||
constructor() {
|
||||
return new Proxy(this, {
|
||||
get(target, prop) {
|
||||
let message
|
||||
const runtime = getRuntime()
|
||||
if (runtime.isEdge) {
|
||||
message = `PrismaClient is not configured to run in ${runtime.prettyName}. In order to run Prisma Client on edge runtime, either:
|
||||
- Use Prisma Accelerate: https://pris.ly/d/accelerate
|
||||
- Use Driver Adapters: https://pris.ly/d/driver-adapters
|
||||
`;
|
||||
} else {
|
||||
message = 'PrismaClient is unable to run in this browser environment, or has been bundled for the browser (running in `' + runtime.prettyName + '`).'
|
||||
}
|
||||
|
||||
message += `
|
||||
If this is unexpected, please open an issue: https://pris.ly/prisma-prisma-bug-report`
|
||||
|
||||
throw new Error(message)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
exports.PrismaClient = PrismaClient
|
||||
|
||||
Object.assign(exports, Prisma)
|
||||
21
backend/node_modules/@cspotcode/source-map-support/LICENSE.md
generated
vendored
Normal file
21
backend/node_modules/@cspotcode/source-map-support/LICENSE.md
generated
vendored
Normal file
@ -0,0 +1,21 @@
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2014 Evan Wallace
|
||||
|
||||
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.
|
||||
289
backend/node_modules/@cspotcode/source-map-support/README.md
generated
vendored
Normal file
289
backend/node_modules/@cspotcode/source-map-support/README.md
generated
vendored
Normal file
@ -0,0 +1,289 @@
|
||||
# Source Map Support
|
||||
|
||||
[](https://npmjs.org/package/@cspotcode/source-map-support)
|
||||
[](https://npmjs.org/package/@cspotcode/source-map-support)
|
||||
[](https://github.com/cspotcode/node-source-map-support/actions?query=workflow%3A%22Continuous+Integration%22)
|
||||
|
||||
This module provides source map support for stack traces in node via the [V8 stack trace API](https://github.com/v8/v8/wiki/Stack-Trace-API). It uses the [source-map](https://github.com/mozilla/source-map) module to replace the paths and line numbers of source-mapped files with their original paths and line numbers. The output mimics node's stack trace format with the goal of making every compile-to-JS language more of a first-class citizen. Source maps are completely general (not specific to any one language) so you can use source maps with multiple compile-to-JS languages in the same node process.
|
||||
|
||||
## Installation and Usage
|
||||
|
||||
#### Node support
|
||||
|
||||
```
|
||||
$ npm install @cspotcode/source-map-support
|
||||
```
|
||||
|
||||
Source maps can be generated using libraries such as [source-map-index-generator](https://github.com/twolfson/source-map-index-generator). Once you have a valid source map, place a source mapping comment somewhere in the file (usually done automatically or with an option by your transpiler):
|
||||
|
||||
```
|
||||
//# sourceMappingURL=path/to/source.map
|
||||
```
|
||||
|
||||
If multiple sourceMappingURL comments exist in one file, the last sourceMappingURL comment will be
|
||||
respected (e.g. if a file mentions the comment in code, or went through multiple transpilers).
|
||||
The path should either be absolute or relative to the compiled file.
|
||||
|
||||
From here you have two options.
|
||||
|
||||
##### CLI Usage
|
||||
|
||||
```bash
|
||||
node -r @cspotcode/source-map-support/register compiled.js
|
||||
# Or to enable hookRequire
|
||||
node -r @cspotcode/source-map-support/register-hook-require compiled.js
|
||||
```
|
||||
|
||||
##### Programmatic Usage
|
||||
|
||||
Put the following line at the top of the compiled file.
|
||||
|
||||
```js
|
||||
require('@cspotcode/source-map-support').install();
|
||||
```
|
||||
|
||||
It is also possible to install the source map support directly by
|
||||
requiring the `register` module which can be handy with ES6:
|
||||
|
||||
```js
|
||||
import '@cspotcode/source-map-support/register'
|
||||
|
||||
// Instead of:
|
||||
import sourceMapSupport from '@cspotcode/source-map-support'
|
||||
sourceMapSupport.install()
|
||||
```
|
||||
Note: if you're using babel-register, it includes source-map-support already.
|
||||
|
||||
It is also very useful with Mocha:
|
||||
|
||||
```
|
||||
$ mocha --require @cspotcode/source-map-support/register tests/
|
||||
```
|
||||
|
||||
#### Browser support
|
||||
|
||||
This library also works in Chrome. While the DevTools console already supports source maps, the V8 engine doesn't and `Error.prototype.stack` will be incorrect without this library. Everything will just work if you deploy your source files using [browserify](http://browserify.org/). Just make sure to pass the `--debug` flag to the browserify command so your source maps are included in the bundled code.
|
||||
|
||||
This library also works if you use another build process or just include the source files directly. In this case, include the file `browser-source-map-support.js` in your page and call `sourceMapSupport.install()`. It contains the whole library already bundled for the browser using browserify.
|
||||
|
||||
```html
|
||||
<script src="browser-source-map-support.js"></script>
|
||||
<script>sourceMapSupport.install();</script>
|
||||
```
|
||||
|
||||
This library also works if you use AMD (Asynchronous Module Definition), which is used in tools like [RequireJS](http://requirejs.org/). Just list `browser-source-map-support` as a dependency:
|
||||
|
||||
```html
|
||||
<script>
|
||||
define(['browser-source-map-support'], function(sourceMapSupport) {
|
||||
sourceMapSupport.install();
|
||||
});
|
||||
</script>
|
||||
```
|
||||
|
||||
## Options
|
||||
|
||||
This module installs two things: a change to the `stack` property on `Error` objects and a handler for uncaught exceptions that mimics node's default exception handler (the handler can be seen in the demos below). You may want to disable the handler if you have your own uncaught exception handler. This can be done by passing an argument to the installer:
|
||||
|
||||
```js
|
||||
require('@cspotcode/source-map-support').install({
|
||||
handleUncaughtExceptions: false
|
||||
});
|
||||
```
|
||||
|
||||
This module loads source maps from the filesystem by default. You can provide alternate loading behavior through a callback as shown below. For example, [Meteor](https://github.com/meteor) keeps all source maps cached in memory to avoid disk access.
|
||||
|
||||
```js
|
||||
require('@cspotcode/source-map-support').install({
|
||||
retrieveSourceMap: function(source) {
|
||||
if (source === 'compiled.js') {
|
||||
return {
|
||||
url: 'original.js',
|
||||
map: fs.readFileSync('compiled.js.map', 'utf8')
|
||||
};
|
||||
}
|
||||
return null;
|
||||
}
|
||||
});
|
||||
```
|
||||
|
||||
The module will by default assume a browser environment if XMLHttpRequest and window are defined. If either of these do not exist it will instead assume a node environment.
|
||||
In some rare cases, e.g. when running a browser emulation and where both variables are also set, you can explictly specify the environment to be either 'browser' or 'node'.
|
||||
|
||||
```js
|
||||
require('@cspotcode/source-map-support').install({
|
||||
environment: 'node'
|
||||
});
|
||||
```
|
||||
|
||||
To support files with inline source maps, the `hookRequire` options can be specified, which will monitor all source files for inline source maps.
|
||||
|
||||
|
||||
```js
|
||||
require('@cspotcode/source-map-support').install({
|
||||
hookRequire: true
|
||||
});
|
||||
```
|
||||
|
||||
This monkey patches the `require` module loading chain, so is not enabled by default and is not recommended for any sort of production usage.
|
||||
|
||||
## Demos
|
||||
|
||||
#### Basic Demo
|
||||
|
||||
original.js:
|
||||
|
||||
```js
|
||||
throw new Error('test'); // This is the original code
|
||||
```
|
||||
|
||||
compiled.js:
|
||||
|
||||
```js
|
||||
require('@cspotcode/source-map-support').install();
|
||||
|
||||
throw new Error('test'); // This is the compiled code
|
||||
// The next line defines the sourceMapping.
|
||||
//# sourceMappingURL=compiled.js.map
|
||||
```
|
||||
|
||||
compiled.js.map:
|
||||
|
||||
```json
|
||||
{
|
||||
"version": 3,
|
||||
"file": "compiled.js",
|
||||
"sources": ["original.js"],
|
||||
"names": [],
|
||||
"mappings": ";;AAAA,MAAM,IAAI"
|
||||
}
|
||||
```
|
||||
|
||||
Run compiled.js using node (notice how the stack trace uses original.js instead of compiled.js):
|
||||
|
||||
```
|
||||
$ node compiled.js
|
||||
|
||||
original.js:1
|
||||
throw new Error('test'); // This is the original code
|
||||
^
|
||||
Error: test
|
||||
at Object.<anonymous> (original.js:1:7)
|
||||
at Module._compile (module.js:456:26)
|
||||
at Object.Module._extensions..js (module.js:474:10)
|
||||
at Module.load (module.js:356:32)
|
||||
at Function.Module._load (module.js:312:12)
|
||||
at Function.Module.runMain (module.js:497:10)
|
||||
at startup (node.js:119:16)
|
||||
at node.js:901:3
|
||||
```
|
||||
|
||||
#### TypeScript Demo
|
||||
|
||||
demo.ts:
|
||||
|
||||
```typescript
|
||||
declare function require(name: string);
|
||||
require('@cspotcode/source-map-support').install();
|
||||
class Foo {
|
||||
constructor() { this.bar(); }
|
||||
bar() { throw new Error('this is a demo'); }
|
||||
}
|
||||
new Foo();
|
||||
```
|
||||
|
||||
Compile and run the file using the TypeScript compiler from the terminal:
|
||||
|
||||
```
|
||||
$ npm install source-map-support typescript
|
||||
$ node_modules/typescript/bin/tsc -sourcemap demo.ts
|
||||
$ node demo.js
|
||||
|
||||
demo.ts:5
|
||||
bar() { throw new Error('this is a demo'); }
|
||||
^
|
||||
Error: this is a demo
|
||||
at Foo.bar (demo.ts:5:17)
|
||||
at new Foo (demo.ts:4:24)
|
||||
at Object.<anonymous> (demo.ts:7:1)
|
||||
at Module._compile (module.js:456:26)
|
||||
at Object.Module._extensions..js (module.js:474:10)
|
||||
at Module.load (module.js:356:32)
|
||||
at Function.Module._load (module.js:312:12)
|
||||
at Function.Module.runMain (module.js:497:10)
|
||||
at startup (node.js:119:16)
|
||||
at node.js:901:3
|
||||
```
|
||||
|
||||
There is also the option to use `-r source-map-support/register` with typescript, without the need add the `require('@cspotcode/source-map-support').install()` in the code base:
|
||||
|
||||
```
|
||||
$ npm install source-map-support typescript
|
||||
$ node_modules/typescript/bin/tsc -sourcemap demo.ts
|
||||
$ node -r source-map-support/register demo.js
|
||||
|
||||
demo.ts:5
|
||||
bar() { throw new Error('this is a demo'); }
|
||||
^
|
||||
Error: this is a demo
|
||||
at Foo.bar (demo.ts:5:17)
|
||||
at new Foo (demo.ts:4:24)
|
||||
at Object.<anonymous> (demo.ts:7:1)
|
||||
at Module._compile (module.js:456:26)
|
||||
at Object.Module._extensions..js (module.js:474:10)
|
||||
at Module.load (module.js:356:32)
|
||||
at Function.Module._load (module.js:312:12)
|
||||
at Function.Module.runMain (module.js:497:10)
|
||||
at startup (node.js:119:16)
|
||||
at node.js:901:3
|
||||
```
|
||||
|
||||
#### CoffeeScript Demo
|
||||
|
||||
demo.coffee:
|
||||
|
||||
```coffee
|
||||
require('@cspotcode/source-map-support').install()
|
||||
foo = ->
|
||||
bar = -> throw new Error 'this is a demo'
|
||||
bar()
|
||||
foo()
|
||||
```
|
||||
|
||||
Compile and run the file using the CoffeeScript compiler from the terminal:
|
||||
|
||||
```sh
|
||||
$ npm install @cspotcode/source-map-support coffeescript
|
||||
$ node_modules/.bin/coffee --map --compile demo.coffee
|
||||
$ node demo.js
|
||||
|
||||
demo.coffee:3
|
||||
bar = -> throw new Error 'this is a demo'
|
||||
^
|
||||
Error: this is a demo
|
||||
at bar (demo.coffee:3:22)
|
||||
at foo (demo.coffee:4:3)
|
||||
at Object.<anonymous> (demo.coffee:5:1)
|
||||
at Object.<anonymous> (demo.coffee:1:1)
|
||||
at Module._compile (module.js:456:26)
|
||||
at Object.Module._extensions..js (module.js:474:10)
|
||||
at Module.load (module.js:356:32)
|
||||
at Function.Module._load (module.js:312:12)
|
||||
at Function.Module.runMain (module.js:497:10)
|
||||
at startup (node.js:119:16)
|
||||
```
|
||||
|
||||
## Tests
|
||||
|
||||
This repo contains both automated tests for node and manual tests for the browser. The automated tests can be run using mocha (type `mocha` in the root directory). To run the manual tests:
|
||||
|
||||
* Build the tests using `build.js`
|
||||
* Launch the HTTP server (`npm run serve-tests`) and visit
|
||||
* http://127.0.0.1:1336/amd-test
|
||||
* http://127.0.0.1:1336/browser-test
|
||||
* http://127.0.0.1:1336/browserify-test - **Currently not working** due to a bug with browserify (see [pull request #66](https://github.com/evanw/node-source-map-support/pull/66) for details).
|
||||
* For `header-test`, run `server.js` inside that directory and visit http://127.0.0.1:1337/
|
||||
|
||||
## License
|
||||
|
||||
This code is available under the [MIT license](http://opensource.org/licenses/MIT).
|
||||
114
backend/node_modules/@cspotcode/source-map-support/browser-source-map-support.js
generated
vendored
Normal file
114
backend/node_modules/@cspotcode/source-map-support/browser-source-map-support.js
generated
vendored
Normal file
@ -0,0 +1,114 @@
|
||||
/*
|
||||
* Support for source maps in V8 stack traces
|
||||
* https://github.com/evanw/node-source-map-support
|
||||
*/
|
||||
/*
|
||||
The buffer module from node.js, for the browser.
|
||||
|
||||
@author Feross Aboukhadijeh <feross@feross.org> <http://feross.org>
|
||||
license MIT
|
||||
*/
|
||||
(this.define||function(R,U){this.sourceMapSupport=U()})("browser-source-map-support",function(R){(function e(C,J,A){function p(f,c){if(!J[f]){if(!C[f]){var l="function"==typeof require&&require;if(!c&&l)return l(f,!0);if(t)return t(f,!0);throw Error("Cannot find module '"+f+"'");}l=J[f]={exports:{}};C[f][0].call(l.exports,function(q){var r=C[f][1][q];return p(r?r:q)},l,l.exports,e,C,J,A)}return J[f].exports}for(var t="function"==typeof require&&require,m=0;m<A.length;m++)p(A[m]);return p})({1:[function(C,
|
||||
J,A){R=C("./source-map-support")},{"./source-map-support":21}],2:[function(C,J,A){(function(e){function p(m){m=m.charCodeAt(0);if(43===m)return 62;if(47===m)return 63;if(48>m)return-1;if(58>m)return m-48+52;if(91>m)return m-65;if(123>m)return m-97+26}var t="undefined"!==typeof Uint8Array?Uint8Array:Array;e.toByteArray=function(m){function f(d){q[k++]=d}if(0<m.length%4)throw Error("Invalid string. Length must be a multiple of 4");var c=m.length;var l="="===m.charAt(c-2)?2:"="===m.charAt(c-1)?1:0;var q=
|
||||
new t(3*m.length/4-l);var r=0<l?m.length-4:m.length;var k=0;for(c=0;c<r;c+=4){var u=p(m.charAt(c))<<18|p(m.charAt(c+1))<<12|p(m.charAt(c+2))<<6|p(m.charAt(c+3));f((u&16711680)>>16);f((u&65280)>>8);f(u&255)}2===l?(u=p(m.charAt(c))<<2|p(m.charAt(c+1))>>4,f(u&255)):1===l&&(u=p(m.charAt(c))<<10|p(m.charAt(c+1))<<4|p(m.charAt(c+2))>>2,f(u>>8&255),f(u&255));return q};e.fromByteArray=function(m){var f=m.length%3,c="",l;var q=0;for(l=m.length-f;q<l;q+=3){var r=(m[q]<<16)+(m[q+1]<<8)+m[q+2];r="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/".charAt(r>>
|
||||
18&63)+"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/".charAt(r>>12&63)+"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/".charAt(r>>6&63)+"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/".charAt(r&63);c+=r}switch(f){case 1:r=m[m.length-1];c+="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/".charAt(r>>2);c+="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/".charAt(r<<4&63);c+="==";break;case 2:r=(m[m.length-2]<<8)+
|
||||
m[m.length-1],c+="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/".charAt(r>>10),c+="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/".charAt(r>>4&63),c+="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/".charAt(r<<2&63),c+="="}return c}})("undefined"===typeof A?this.base64js={}:A)},{}],3:[function(C,J,A){},{}],4:[function(C,J,A){(function(e){var p=Object.prototype.toString,t="function"===typeof e.alloc&&"function"===typeof e.allocUnsafe&&"function"===
|
||||
typeof e.from;J.exports=function(m,f,c){if("number"===typeof m)throw new TypeError('"value" argument must not be a number');if("ArrayBuffer"===p.call(m).slice(8,-1)){f>>>=0;var l=m.byteLength-f;if(0>l)throw new RangeError("'offset' is out of bounds");if(void 0===c)c=l;else if(c>>>=0,c>l)throw new RangeError("'length' is out of bounds");return t?e.from(m.slice(f,f+c)):new e(new Uint8Array(m.slice(f,f+c)))}if("string"===typeof m){c=f;if("string"!==typeof c||""===c)c="utf8";if(!e.isEncoding(c))throw new TypeError('"encoding" must be a valid string encoding');
|
||||
return t?e.from(m,c):new e(m,c)}return t?e.from(m):new e(m)}}).call(this,C("buffer").Buffer)},{buffer:5}],5:[function(C,J,A){function e(a,b,h){if(!(this instanceof e))return new e(a,b,h);var w=typeof a;if("number"===w)var y=0<a?a>>>0:0;else if("string"===w){if("base64"===b)for(a=(a.trim?a.trim():a.replace(/^\s+|\s+$/g,"")).replace(L,"");0!==a.length%4;)a+="=";y=e.byteLength(a,b)}else if("object"===w&&null!==a)"Buffer"===a.type&&z(a.data)&&(a=a.data),y=0<+a.length?Math.floor(+a.length):0;else throw new TypeError("must start with number, buffer, array or string");
|
||||
if(this.length>G)throw new RangeError("Attempt to allocate Buffer larger than maximum size: 0x"+G.toString(16)+" bytes");if(e.TYPED_ARRAY_SUPPORT)var I=e._augment(new Uint8Array(y));else I=this,I.length=y,I._isBuffer=!0;if(e.TYPED_ARRAY_SUPPORT&&"number"===typeof a.byteLength)I._set(a);else{var K=a;if(z(K)||e.isBuffer(K)||K&&"object"===typeof K&&"number"===typeof K.length)if(e.isBuffer(a))for(b=0;b<y;b++)I[b]=a.readUInt8(b);else for(b=0;b<y;b++)I[b]=(a[b]%256+256)%256;else if("string"===w)I.write(a,
|
||||
0,b);else if("number"===w&&!e.TYPED_ARRAY_SUPPORT&&!h)for(b=0;b<y;b++)I[b]=0}return I}function p(a,b,h){var w="";for(h=Math.min(a.length,h);b<h;b++)w+=String.fromCharCode(a[b]);return w}function t(a,b,h){if(0!==a%1||0>a)throw new RangeError("offset is not uint");if(a+b>h)throw new RangeError("Trying to access beyond buffer length");}function m(a,b,h,w,y,I){if(!e.isBuffer(a))throw new TypeError("buffer must be a Buffer instance");if(b>y||b<I)throw new TypeError("value is out of bounds");if(h+w>a.length)throw new TypeError("index out of range");
|
||||
}function f(a,b,h,w){0>b&&(b=65535+b+1);for(var y=0,I=Math.min(a.length-h,2);y<I;y++)a[h+y]=(b&255<<8*(w?y:1-y))>>>8*(w?y:1-y)}function c(a,b,h,w){0>b&&(b=4294967295+b+1);for(var y=0,I=Math.min(a.length-h,4);y<I;y++)a[h+y]=b>>>8*(w?y:3-y)&255}function l(a,b,h,w,y,I){if(b>y||b<I)throw new TypeError("value is out of bounds");if(h+w>a.length)throw new TypeError("index out of range");}function q(a,b,h,w,y){y||l(a,b,h,4,3.4028234663852886E38,-3.4028234663852886E38);v.write(a,b,h,w,23,4);return h+4}function r(a,
|
||||
b,h,w,y){y||l(a,b,h,8,1.7976931348623157E308,-1.7976931348623157E308);v.write(a,b,h,w,52,8);return h+8}function k(a){for(var b=[],h=0;h<a.length;h++){var w=a.charCodeAt(h);if(127>=w)b.push(w);else{var y=h;55296<=w&&57343>=w&&h++;w=encodeURIComponent(a.slice(y,h+1)).substr(1).split("%");for(y=0;y<w.length;y++)b.push(parseInt(w[y],16))}}return b}function u(a){for(var b=[],h=0;h<a.length;h++)b.push(a.charCodeAt(h)&255);return b}function d(a,b,h,w,y){y&&(w-=w%y);for(y=0;y<w&&!(y+h>=b.length||y>=a.length);y++)b[y+
|
||||
h]=a[y];return y}function g(a){try{return decodeURIComponent(a)}catch(b){return String.fromCharCode(65533)}}var n=C("base64-js"),v=C("ieee754"),z=C("is-array");A.Buffer=e;A.SlowBuffer=e;A.INSPECT_MAX_BYTES=50;e.poolSize=8192;var G=1073741823;e.TYPED_ARRAY_SUPPORT=function(){try{var a=new ArrayBuffer(0),b=new Uint8Array(a);b.foo=function(){return 42};return 42===b.foo()&&"function"===typeof b.subarray&&0===(new Uint8Array(1)).subarray(1,1).byteLength}catch(h){return!1}}();e.isBuffer=function(a){return!(null==
|
||||
a||!a._isBuffer)};e.compare=function(a,b){if(!e.isBuffer(a)||!e.isBuffer(b))throw new TypeError("Arguments must be Buffers");for(var h=a.length,w=b.length,y=0,I=Math.min(h,w);y<I&&a[y]===b[y];y++);y!==I&&(h=a[y],w=b[y]);return h<w?-1:w<h?1:0};e.isEncoding=function(a){switch(String(a).toLowerCase()){case "hex":case "utf8":case "utf-8":case "ascii":case "binary":case "base64":case "raw":case "ucs2":case "ucs-2":case "utf16le":case "utf-16le":return!0;default:return!1}};e.concat=function(a,b){if(!z(a))throw new TypeError("Usage: Buffer.concat(list[, length])");
|
||||
if(0===a.length)return new e(0);if(1===a.length)return a[0];var h;if(void 0===b)for(h=b=0;h<a.length;h++)b+=a[h].length;var w=new e(b),y=0;for(h=0;h<a.length;h++){var I=a[h];I.copy(w,y);y+=I.length}return w};e.byteLength=function(a,b){a+="";switch(b||"utf8"){case "ascii":case "binary":case "raw":var h=a.length;break;case "ucs2":case "ucs-2":case "utf16le":case "utf-16le":h=2*a.length;break;case "hex":h=a.length>>>1;break;case "utf8":case "utf-8":h=k(a).length;break;case "base64":h=n.toByteArray(a).length;
|
||||
break;default:h=a.length}return h};e.prototype.length=void 0;e.prototype.parent=void 0;e.prototype.toString=function(a,b,h){var w=!1;b>>>=0;h=void 0===h||Infinity===h?this.length:h>>>0;a||(a="utf8");0>b&&(b=0);h>this.length&&(h=this.length);if(h<=b)return"";for(;;)switch(a){case "hex":a=b;b=h;h=this.length;if(!a||0>a)a=0;if(!b||0>b||b>h)b=h;w="";for(h=a;h<b;h++)a=w,w=this[h],w=16>w?"0"+w.toString(16):w.toString(16),w=a+w;return w;case "utf8":case "utf-8":w=a="";for(h=Math.min(this.length,h);b<h;b++)127>=
|
||||
this[b]?(a+=g(w)+String.fromCharCode(this[b]),w=""):w+="%"+this[b].toString(16);return a+g(w);case "ascii":return p(this,b,h);case "binary":return p(this,b,h);case "base64":return b=0===b&&h===this.length?n.fromByteArray(this):n.fromByteArray(this.slice(b,h)),b;case "ucs2":case "ucs-2":case "utf16le":case "utf-16le":b=this.slice(b,h);h="";for(a=0;a<b.length;a+=2)h+=String.fromCharCode(b[a]+256*b[a+1]);return h;default:if(w)throw new TypeError("Unknown encoding: "+a);a=(a+"").toLowerCase();w=!0}};
|
||||
e.prototype.equals=function(a){if(!e.isBuffer(a))throw new TypeError("Argument must be a Buffer");return 0===e.compare(this,a)};e.prototype.inspect=function(){var a="",b=A.INSPECT_MAX_BYTES;0<this.length&&(a=this.toString("hex",0,b).match(/.{2}/g).join(" "),this.length>b&&(a+=" ... "));return"<Buffer "+a+">"};e.prototype.compare=function(a){if(!e.isBuffer(a))throw new TypeError("Argument must be a Buffer");return e.compare(this,a)};e.prototype.get=function(a){console.log(".get() is deprecated. Access using array indexes instead.");
|
||||
return this.readUInt8(a)};e.prototype.set=function(a,b){console.log(".set() is deprecated. Access using array indexes instead.");return this.writeUInt8(a,b)};e.prototype.write=function(a,b,h,w){if(isFinite(b))isFinite(h)||(w=h,h=void 0);else{var y=w;w=b;b=h;h=y}b=Number(b)||0;y=this.length-b;h?(h=Number(h),h>y&&(h=y)):h=y;w=String(w||"utf8").toLowerCase();switch(w){case "hex":b=Number(b)||0;w=this.length-b;h?(h=Number(h),h>w&&(h=w)):h=w;w=a.length;if(0!==w%2)throw Error("Invalid hex string");h>w/
|
||||
2&&(h=w/2);for(w=0;w<h;w++){y=parseInt(a.substr(2*w,2),16);if(isNaN(y))throw Error("Invalid hex string");this[b+w]=y}a=w;break;case "utf8":case "utf-8":a=d(k(a),this,b,h);break;case "ascii":a=d(u(a),this,b,h);break;case "binary":a=d(u(a),this,b,h);break;case "base64":a=d(n.toByteArray(a),this,b,h);break;case "ucs2":case "ucs-2":case "utf16le":case "utf-16le":y=[];for(var I=0;I<a.length;I++){var K=a.charCodeAt(I);w=K>>8;K%=256;y.push(K);y.push(w)}a=d(y,this,b,h,2);break;default:throw new TypeError("Unknown encoding: "+
|
||||
w);}return a};e.prototype.toJSON=function(){return{type:"Buffer",data:Array.prototype.slice.call(this._arr||this,0)}};e.prototype.slice=function(a,b){var h=this.length;a=~~a;b=void 0===b?h:~~b;0>a?(a+=h,0>a&&(a=0)):a>h&&(a=h);0>b?(b+=h,0>b&&(b=0)):b>h&&(b=h);b<a&&(b=a);if(e.TYPED_ARRAY_SUPPORT)return e._augment(this.subarray(a,b));h=b-a;for(var w=new e(h,void 0,!0),y=0;y<h;y++)w[y]=this[y+a];return w};e.prototype.readUInt8=function(a,b){b||t(a,1,this.length);return this[a]};e.prototype.readUInt16LE=
|
||||
function(a,b){b||t(a,2,this.length);return this[a]|this[a+1]<<8};e.prototype.readUInt16BE=function(a,b){b||t(a,2,this.length);return this[a]<<8|this[a+1]};e.prototype.readUInt32LE=function(a,b){b||t(a,4,this.length);return(this[a]|this[a+1]<<8|this[a+2]<<16)+16777216*this[a+3]};e.prototype.readUInt32BE=function(a,b){b||t(a,4,this.length);return 16777216*this[a]+(this[a+1]<<16|this[a+2]<<8|this[a+3])};e.prototype.readInt8=function(a,b){b||t(a,1,this.length);return this[a]&128?-1*(255-this[a]+1):this[a]};
|
||||
e.prototype.readInt16LE=function(a,b){b||t(a,2,this.length);var h=this[a]|this[a+1]<<8;return h&32768?h|4294901760:h};e.prototype.readInt16BE=function(a,b){b||t(a,2,this.length);var h=this[a+1]|this[a]<<8;return h&32768?h|4294901760:h};e.prototype.readInt32LE=function(a,b){b||t(a,4,this.length);return this[a]|this[a+1]<<8|this[a+2]<<16|this[a+3]<<24};e.prototype.readInt32BE=function(a,b){b||t(a,4,this.length);return this[a]<<24|this[a+1]<<16|this[a+2]<<8|this[a+3]};e.prototype.readFloatLE=function(a,
|
||||
b){b||t(a,4,this.length);return v.read(this,a,!0,23,4)};e.prototype.readFloatBE=function(a,b){b||t(a,4,this.length);return v.read(this,a,!1,23,4)};e.prototype.readDoubleLE=function(a,b){b||t(a,8,this.length);return v.read(this,a,!0,52,8)};e.prototype.readDoubleBE=function(a,b){b||t(a,8,this.length);return v.read(this,a,!1,52,8)};e.prototype.writeUInt8=function(a,b,h){a=+a;b>>>=0;h||m(this,a,b,1,255,0);e.TYPED_ARRAY_SUPPORT||(a=Math.floor(a));this[b]=a;return b+1};e.prototype.writeUInt16LE=function(a,
|
||||
b,h){a=+a;b>>>=0;h||m(this,a,b,2,65535,0);e.TYPED_ARRAY_SUPPORT?(this[b]=a,this[b+1]=a>>>8):f(this,a,b,!0);return b+2};e.prototype.writeUInt16BE=function(a,b,h){a=+a;b>>>=0;h||m(this,a,b,2,65535,0);e.TYPED_ARRAY_SUPPORT?(this[b]=a>>>8,this[b+1]=a):f(this,a,b,!1);return b+2};e.prototype.writeUInt32LE=function(a,b,h){a=+a;b>>>=0;h||m(this,a,b,4,4294967295,0);e.TYPED_ARRAY_SUPPORT?(this[b+3]=a>>>24,this[b+2]=a>>>16,this[b+1]=a>>>8,this[b]=a):c(this,a,b,!0);return b+4};e.prototype.writeUInt32BE=function(a,
|
||||
b,h){a=+a;b>>>=0;h||m(this,a,b,4,4294967295,0);e.TYPED_ARRAY_SUPPORT?(this[b]=a>>>24,this[b+1]=a>>>16,this[b+2]=a>>>8,this[b+3]=a):c(this,a,b,!1);return b+4};e.prototype.writeInt8=function(a,b,h){a=+a;b>>>=0;h||m(this,a,b,1,127,-128);e.TYPED_ARRAY_SUPPORT||(a=Math.floor(a));0>a&&(a=255+a+1);this[b]=a;return b+1};e.prototype.writeInt16LE=function(a,b,h){a=+a;b>>>=0;h||m(this,a,b,2,32767,-32768);e.TYPED_ARRAY_SUPPORT?(this[b]=a,this[b+1]=a>>>8):f(this,a,b,!0);return b+2};e.prototype.writeInt16BE=function(a,
|
||||
b,h){a=+a;b>>>=0;h||m(this,a,b,2,32767,-32768);e.TYPED_ARRAY_SUPPORT?(this[b]=a>>>8,this[b+1]=a):f(this,a,b,!1);return b+2};e.prototype.writeInt32LE=function(a,b,h){a=+a;b>>>=0;h||m(this,a,b,4,2147483647,-2147483648);e.TYPED_ARRAY_SUPPORT?(this[b]=a,this[b+1]=a>>>8,this[b+2]=a>>>16,this[b+3]=a>>>24):c(this,a,b,!0);return b+4};e.prototype.writeInt32BE=function(a,b,h){a=+a;b>>>=0;h||m(this,a,b,4,2147483647,-2147483648);0>a&&(a=4294967295+a+1);e.TYPED_ARRAY_SUPPORT?(this[b]=a>>>24,this[b+1]=a>>>16,this[b+
|
||||
2]=a>>>8,this[b+3]=a):c(this,a,b,!1);return b+4};e.prototype.writeFloatLE=function(a,b,h){return q(this,a,b,!0,h)};e.prototype.writeFloatBE=function(a,b,h){return q(this,a,b,!1,h)};e.prototype.writeDoubleLE=function(a,b,h){return r(this,a,b,!0,h)};e.prototype.writeDoubleBE=function(a,b,h){return r(this,a,b,!1,h)};e.prototype.copy=function(a,b,h,w){h||(h=0);w||0===w||(w=this.length);b||(b=0);if(w!==h&&0!==a.length&&0!==this.length){if(w<h)throw new TypeError("sourceEnd < sourceStart");if(0>b||b>=a.length)throw new TypeError("targetStart out of bounds");
|
||||
if(0>h||h>=this.length)throw new TypeError("sourceStart out of bounds");if(0>w||w>this.length)throw new TypeError("sourceEnd out of bounds");w>this.length&&(w=this.length);a.length-b<w-h&&(w=a.length-b+h);w-=h;if(1E3>w||!e.TYPED_ARRAY_SUPPORT)for(var y=0;y<w;y++)a[y+b]=this[y+h];else a._set(this.subarray(h,h+w),b)}};e.prototype.fill=function(a,b,h){a||(a=0);b||(b=0);h||(h=this.length);if(h<b)throw new TypeError("end < start");if(h!==b&&0!==this.length){if(0>b||b>=this.length)throw new TypeError("start out of bounds");
|
||||
if(0>h||h>this.length)throw new TypeError("end out of bounds");if("number"===typeof a)for(;b<h;b++)this[b]=a;else{a=k(a.toString());for(var w=a.length;b<h;b++)this[b]=a[b%w]}return this}};e.prototype.toArrayBuffer=function(){if("undefined"!==typeof Uint8Array){if(e.TYPED_ARRAY_SUPPORT)return(new e(this)).buffer;for(var a=new Uint8Array(this.length),b=0,h=a.length;b<h;b+=1)a[b]=this[b];return a.buffer}throw new TypeError("Buffer.toArrayBuffer not supported in this browser");};var D=e.prototype;e._augment=
|
||||
function(a){a.constructor=e;a._isBuffer=!0;a._get=a.get;a._set=a.set;a.get=D.get;a.set=D.set;a.write=D.write;a.toString=D.toString;a.toLocaleString=D.toString;a.toJSON=D.toJSON;a.equals=D.equals;a.compare=D.compare;a.copy=D.copy;a.slice=D.slice;a.readUInt8=D.readUInt8;a.readUInt16LE=D.readUInt16LE;a.readUInt16BE=D.readUInt16BE;a.readUInt32LE=D.readUInt32LE;a.readUInt32BE=D.readUInt32BE;a.readInt8=D.readInt8;a.readInt16LE=D.readInt16LE;a.readInt16BE=D.readInt16BE;a.readInt32LE=D.readInt32LE;a.readInt32BE=
|
||||
D.readInt32BE;a.readFloatLE=D.readFloatLE;a.readFloatBE=D.readFloatBE;a.readDoubleLE=D.readDoubleLE;a.readDoubleBE=D.readDoubleBE;a.writeUInt8=D.writeUInt8;a.writeUInt16LE=D.writeUInt16LE;a.writeUInt16BE=D.writeUInt16BE;a.writeUInt32LE=D.writeUInt32LE;a.writeUInt32BE=D.writeUInt32BE;a.writeInt8=D.writeInt8;a.writeInt16LE=D.writeInt16LE;a.writeInt16BE=D.writeInt16BE;a.writeInt32LE=D.writeInt32LE;a.writeInt32BE=D.writeInt32BE;a.writeFloatLE=D.writeFloatLE;a.writeFloatBE=D.writeFloatBE;a.writeDoubleLE=
|
||||
D.writeDoubleLE;a.writeDoubleBE=D.writeDoubleBE;a.fill=D.fill;a.inspect=D.inspect;a.toArrayBuffer=D.toArrayBuffer;return a};var L=/[^+\/0-9A-z]/g},{"base64-js":2,ieee754:6,"is-array":7}],6:[function(C,J,A){A.read=function(e,p,t,m,f){var c=8*f-m-1;var l=(1<<c)-1,q=l>>1,r=-7;f=t?f-1:0;var k=t?-1:1,u=e[p+f];f+=k;t=u&(1<<-r)-1;u>>=-r;for(r+=c;0<r;t=256*t+e[p+f],f+=k,r-=8);c=t&(1<<-r)-1;t>>=-r;for(r+=m;0<r;c=256*c+e[p+f],f+=k,r-=8);if(0===t)t=1-q;else{if(t===l)return c?NaN:Infinity*(u?-1:1);c+=Math.pow(2,
|
||||
m);t-=q}return(u?-1:1)*c*Math.pow(2,t-m)};A.write=function(e,p,t,m,f,c){var l,q=8*c-f-1,r=(1<<q)-1,k=r>>1,u=23===f?Math.pow(2,-24)-Math.pow(2,-77):0;c=m?0:c-1;var d=m?1:-1,g=0>p||0===p&&0>1/p?1:0;p=Math.abs(p);isNaN(p)||Infinity===p?(p=isNaN(p)?1:0,m=r):(m=Math.floor(Math.log(p)/Math.LN2),1>p*(l=Math.pow(2,-m))&&(m--,l*=2),p=1<=m+k?p+u/l:p+u*Math.pow(2,1-k),2<=p*l&&(m++,l/=2),m+k>=r?(p=0,m=r):1<=m+k?(p=(p*l-1)*Math.pow(2,f),m+=k):(p=p*Math.pow(2,k-1)*Math.pow(2,f),m=0));for(;8<=f;e[t+c]=p&255,c+=
|
||||
d,p/=256,f-=8);m=m<<f|p;for(q+=f;0<q;e[t+c]=m&255,c+=d,m/=256,q-=8);e[t+c-d]|=128*g}},{}],7:[function(C,J,A){var e=Object.prototype.toString;J.exports=Array.isArray||function(p){return!!p&&"[object Array]"==e.call(p)}},{}],8:[function(C,J,A){(function(e){function p(c,l){for(var q=0,r=c.length-1;0<=r;r--){var k=c[r];"."===k?c.splice(r,1):".."===k?(c.splice(r,1),q++):q&&(c.splice(r,1),q--)}if(l)for(;q--;q)c.unshift("..");return c}function t(c,l){if(c.filter)return c.filter(l);for(var q=[],r=0;r<c.length;r++)l(c[r],
|
||||
r,c)&&q.push(c[r]);return q}var m=/^(\/?|)([\s\S]*?)((?:\.{1,2}|[^\/]+?|)(\.[^.\/]*|))(?:[\/]*)$/;A.resolve=function(){for(var c="",l=!1,q=arguments.length-1;-1<=q&&!l;q--){var r=0<=q?arguments[q]:e.cwd();if("string"!==typeof r)throw new TypeError("Arguments to path.resolve must be strings");r&&(c=r+"/"+c,l="/"===r.charAt(0))}c=p(t(c.split("/"),function(k){return!!k}),!l).join("/");return(l?"/":"")+c||"."};A.normalize=function(c){var l=A.isAbsolute(c),q="/"===f(c,-1);(c=p(t(c.split("/"),function(r){return!!r}),
|
||||
!l).join("/"))||l||(c=".");c&&q&&(c+="/");return(l?"/":"")+c};A.isAbsolute=function(c){return"/"===c.charAt(0)};A.join=function(){var c=Array.prototype.slice.call(arguments,0);return A.normalize(t(c,function(l,q){if("string"!==typeof l)throw new TypeError("Arguments to path.join must be strings");return l}).join("/"))};A.relative=function(c,l){function q(n){for(var v=0;v<n.length&&""===n[v];v++);for(var z=n.length-1;0<=z&&""===n[z];z--);return v>z?[]:n.slice(v,z-v+1)}c=A.resolve(c).substr(1);l=A.resolve(l).substr(1);
|
||||
for(var r=q(c.split("/")),k=q(l.split("/")),u=Math.min(r.length,k.length),d=u,g=0;g<u;g++)if(r[g]!==k[g]){d=g;break}u=[];for(g=d;g<r.length;g++)u.push("..");u=u.concat(k.slice(d));return u.join("/")};A.sep="/";A.delimiter=":";A.dirname=function(c){var l=m.exec(c).slice(1);c=l[0];l=l[1];if(!c&&!l)return".";l&&(l=l.substr(0,l.length-1));return c+l};A.basename=function(c,l){var q=m.exec(c).slice(1)[2];l&&q.substr(-1*l.length)===l&&(q=q.substr(0,q.length-l.length));return q};A.extname=function(c){return m.exec(c).slice(1)[3]};
|
||||
var f="b"==="ab".substr(-1)?function(c,l,q){return c.substr(l,q)}:function(c,l,q){0>l&&(l=c.length+l);return c.substr(l,q)}}).call(this,C("g5I+bs"))},{"g5I+bs":9}],9:[function(C,J,A){function e(){}C=J.exports={};C.nextTick=function(){if("undefined"!==typeof window&&window.setImmediate)return function(t){return window.setImmediate(t)};if("undefined"!==typeof window&&window.postMessage&&window.addEventListener){var p=[];window.addEventListener("message",function(t){var m=t.source;m!==window&&null!==
|
||||
m||"process-tick"!==t.data||(t.stopPropagation(),0<p.length&&p.shift()())},!0);return function(t){p.push(t);window.postMessage("process-tick","*")}}return function(t){setTimeout(t,0)}}();C.title="browser";C.browser=!0;C.env={};C.argv=[];C.on=e;C.addListener=e;C.once=e;C.off=e;C.removeListener=e;C.removeAllListeners=e;C.emit=e;C.binding=function(p){throw Error("process.binding is not supported");};C.cwd=function(){return"/"};C.chdir=function(p){throw Error("process.chdir is not supported");}},{}],
|
||||
10:[function(C,J,A){function e(){this._array=[];this._set=m?new Map:Object.create(null)}var p=C("./util"),t=Object.prototype.hasOwnProperty,m="undefined"!==typeof Map;e.fromArray=function(f,c){for(var l=new e,q=0,r=f.length;q<r;q++)l.add(f[q],c);return l};e.prototype.size=function(){return m?this._set.size:Object.getOwnPropertyNames(this._set).length};e.prototype.add=function(f,c){var l=m?f:p.toSetString(f),q=m?this.has(f):t.call(this._set,l),r=this._array.length;q&&!c||this._array.push(f);q||(m?
|
||||
this._set.set(f,r):this._set[l]=r)};e.prototype.has=function(f){if(m)return this._set.has(f);f=p.toSetString(f);return t.call(this._set,f)};e.prototype.indexOf=function(f){if(m){var c=this._set.get(f);if(0<=c)return c}else if(c=p.toSetString(f),t.call(this._set,c))return this._set[c];throw Error('"'+f+'" is not in the set.');};e.prototype.at=function(f){if(0<=f&&f<this._array.length)return this._array[f];throw Error("No element indexed by "+f);};e.prototype.toArray=function(){return this._array.slice()};
|
||||
A.ArraySet=e},{"./util":19}],11:[function(C,J,A){var e=C("./base64");A.encode=function(p){var t="",m=0>p?(-p<<1)+1:p<<1;do p=m&31,m>>>=5,0<m&&(p|=32),t+=e.encode(p);while(0<m);return t};A.decode=function(p,t,m){var f=p.length,c=0,l=0;do{if(t>=f)throw Error("Expected more digits in base 64 VLQ value.");var q=e.decode(p.charCodeAt(t++));if(-1===q)throw Error("Invalid base64 digit: "+p.charAt(t-1));var r=!!(q&32);q&=31;c+=q<<l;l+=5}while(r);p=c>>1;m.value=1===(c&1)?-p:p;m.rest=t}},{"./base64":12}],12:[function(C,
|
||||
J,A){var e="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/".split("");A.encode=function(p){if(0<=p&&p<e.length)return e[p];throw new TypeError("Must be between 0 and 63: "+p);};A.decode=function(p){return 65<=p&&90>=p?p-65:97<=p&&122>=p?p-97+26:48<=p&&57>=p?p-48+52:43==p?62:47==p?63:-1}},{}],13:[function(C,J,A){function e(p,t,m,f,c,l){var q=Math.floor((t-p)/2)+p,r=c(m,f[q],!0);return 0===r?q:0<r?1<t-q?e(q,t,m,f,c,l):l==A.LEAST_UPPER_BOUND?t<f.length?t:-1:q:1<q-p?e(p,q,m,f,c,l):l==
|
||||
A.LEAST_UPPER_BOUND?q:0>p?-1:p}A.GREATEST_LOWER_BOUND=1;A.LEAST_UPPER_BOUND=2;A.search=function(p,t,m,f){if(0===t.length)return-1;p=e(-1,t.length,p,t,m,f||A.GREATEST_LOWER_BOUND);if(0>p)return-1;for(;0<=p-1&&0===m(t[p],t[p-1],!0);)--p;return p}},{}],14:[function(C,J,A){function e(){this._array=[];this._sorted=!0;this._last={generatedLine:-1,generatedColumn:0}}var p=C("./util");e.prototype.unsortedForEach=function(t,m){this._array.forEach(t,m)};e.prototype.add=function(t){var m=this._last,f=m.generatedLine,
|
||||
c=t.generatedLine,l=m.generatedColumn,q=t.generatedColumn;c>f||c==f&&q>=l||0>=p.compareByGeneratedPositionsInflated(m,t)?this._last=t:this._sorted=!1;this._array.push(t)};e.prototype.toArray=function(){this._sorted||(this._array.sort(p.compareByGeneratedPositionsInflated),this._sorted=!0);return this._array};A.MappingList=e},{"./util":19}],15:[function(C,J,A){function e(t,m,f){var c=t[m];t[m]=t[f];t[f]=c}function p(t,m,f,c){if(f<c){var l=f-1;e(t,Math.round(f+Math.random()*(c-f)),c);for(var q=t[c],
|
||||
r=f;r<c;r++)0>=m(t[r],q)&&(l+=1,e(t,l,r));e(t,l+1,r);l+=1;p(t,m,f,l-1);p(t,m,l+1,c)}}A.quickSort=function(t,m){p(t,m,0,t.length-1)}},{}],16:[function(C,J,A){function e(k,u){var d=k;"string"===typeof k&&(d=f.parseSourceMapInput(k));return null!=d.sections?new m(d,u):new p(d,u)}function p(k,u){var d=k;"string"===typeof k&&(d=f.parseSourceMapInput(k));var g=f.getArg(d,"version"),n=f.getArg(d,"sources"),v=f.getArg(d,"names",[]),z=f.getArg(d,"sourceRoot",null),G=f.getArg(d,"sourcesContent",null),D=f.getArg(d,
|
||||
"mappings");d=f.getArg(d,"file",null);if(g!=this._version)throw Error("Unsupported version: "+g);z&&(z=f.normalize(z));n=n.map(String).map(f.normalize).map(function(L){return z&&f.isAbsolute(z)&&f.isAbsolute(L)?f.relative(z,L):L});this._names=l.fromArray(v.map(String),!0);this._sources=l.fromArray(n,!0);this.sourceRoot=z;this.sourcesContent=G;this._mappings=D;this._sourceMapURL=u;this.file=d}function t(){this.generatedColumn=this.generatedLine=0;this.name=this.originalColumn=this.originalLine=this.source=
|
||||
null}function m(k,u){var d=k;"string"===typeof k&&(d=f.parseSourceMapInput(k));var g=f.getArg(d,"version");d=f.getArg(d,"sections");if(g!=this._version)throw Error("Unsupported version: "+g);this._sources=new l;this._names=new l;var n={line:-1,column:0};this._sections=d.map(function(v){if(v.url)throw Error("Support for url field in sections not implemented.");var z=f.getArg(v,"offset"),G=f.getArg(z,"line"),D=f.getArg(z,"column");if(G<n.line||G===n.line&&D<n.column)throw Error("Section offsets must be ordered and non-overlapping.");
|
||||
n=z;return{generatedOffset:{generatedLine:G+1,generatedColumn:D+1},consumer:new e(f.getArg(v,"map"),u)}})}var f=C("./util"),c=C("./binary-search"),l=C("./array-set").ArraySet,q=C("./base64-vlq"),r=C("./quick-sort").quickSort;e.fromSourceMap=function(k){return p.fromSourceMap(k)};e.prototype._version=3;e.prototype.__generatedMappings=null;Object.defineProperty(e.prototype,"_generatedMappings",{configurable:!0,enumerable:!0,get:function(){this.__generatedMappings||this._parseMappings(this._mappings,
|
||||
this.sourceRoot);return this.__generatedMappings}});e.prototype.__originalMappings=null;Object.defineProperty(e.prototype,"_originalMappings",{configurable:!0,enumerable:!0,get:function(){this.__originalMappings||this._parseMappings(this._mappings,this.sourceRoot);return this.__originalMappings}});e.prototype._charIsMappingSeparator=function(k,u){var d=k.charAt(u);return";"===d||","===d};e.prototype._parseMappings=function(k,u){throw Error("Subclasses must implement _parseMappings");};e.GENERATED_ORDER=
|
||||
1;e.ORIGINAL_ORDER=2;e.GREATEST_LOWER_BOUND=1;e.LEAST_UPPER_BOUND=2;e.prototype.eachMapping=function(k,u,d){u=u||null;switch(d||e.GENERATED_ORDER){case e.GENERATED_ORDER:d=this._generatedMappings;break;case e.ORIGINAL_ORDER:d=this._originalMappings;break;default:throw Error("Unknown order of iteration.");}var g=this.sourceRoot;d.map(function(n){var v=null===n.source?null:this._sources.at(n.source);v=f.computeSourceURL(g,v,this._sourceMapURL);return{source:v,generatedLine:n.generatedLine,generatedColumn:n.generatedColumn,
|
||||
originalLine:n.originalLine,originalColumn:n.originalColumn,name:null===n.name?null:this._names.at(n.name)}},this).forEach(k,u)};e.prototype.allGeneratedPositionsFor=function(k){var u=f.getArg(k,"line"),d={source:f.getArg(k,"source"),originalLine:u,originalColumn:f.getArg(k,"column",0)};null!=this.sourceRoot&&(d.source=f.relative(this.sourceRoot,d.source));if(!this._sources.has(d.source))return[];d.source=this._sources.indexOf(d.source);var g=[];d=this._findMapping(d,this._originalMappings,"originalLine",
|
||||
"originalColumn",f.compareByOriginalPositions,c.LEAST_UPPER_BOUND);if(0<=d){var n=this._originalMappings[d];if(void 0===k.column)for(u=n.originalLine;n&&n.originalLine===u;)g.push({line:f.getArg(n,"generatedLine",null),column:f.getArg(n,"generatedColumn",null),lastColumn:f.getArg(n,"lastGeneratedColumn",null)}),n=this._originalMappings[++d];else for(k=n.originalColumn;n&&n.originalLine===u&&n.originalColumn==k;)g.push({line:f.getArg(n,"generatedLine",null),column:f.getArg(n,"generatedColumn",null),
|
||||
lastColumn:f.getArg(n,"lastGeneratedColumn",null)}),n=this._originalMappings[++d]}return g};A.SourceMapConsumer=e;p.prototype=Object.create(e.prototype);p.prototype.consumer=e;p.fromSourceMap=function(k,u){var d=Object.create(p.prototype),g=d._names=l.fromArray(k._names.toArray(),!0),n=d._sources=l.fromArray(k._sources.toArray(),!0);d.sourceRoot=k._sourceRoot;d.sourcesContent=k._generateSourcesContent(d._sources.toArray(),d.sourceRoot);d.file=k._file;d._sourceMapURL=u;for(var v=k._mappings.toArray().slice(),
|
||||
z=d.__generatedMappings=[],G=d.__originalMappings=[],D=0,L=v.length;D<L;D++){var a=v[D],b=new t;b.generatedLine=a.generatedLine;b.generatedColumn=a.generatedColumn;a.source&&(b.source=n.indexOf(a.source),b.originalLine=a.originalLine,b.originalColumn=a.originalColumn,a.name&&(b.name=g.indexOf(a.name)),G.push(b));z.push(b)}r(d.__originalMappings,f.compareByOriginalPositions);return d};p.prototype._version=3;Object.defineProperty(p.prototype,"sources",{get:function(){return this._sources.toArray().map(function(k){return f.computeSourceURL(this.sourceRoot,
|
||||
k,this._sourceMapURL)},this)}});p.prototype._parseMappings=function(k,u){for(var d=1,g=0,n=0,v=0,z=0,G=0,D=k.length,L=0,a={},b={},h=[],w=[],y,I,K,N,P;L<D;)if(";"===k.charAt(L))d++,L++,g=0;else if(","===k.charAt(L))L++;else{y=new t;y.generatedLine=d;for(N=L;N<D&&!this._charIsMappingSeparator(k,N);N++);I=k.slice(L,N);if(K=a[I])L+=I.length;else{for(K=[];L<N;)q.decode(k,L,b),P=b.value,L=b.rest,K.push(P);if(2===K.length)throw Error("Found a source, but no line and column");if(3===K.length)throw Error("Found a source and line, but no column");
|
||||
a[I]=K}y.generatedColumn=g+K[0];g=y.generatedColumn;1<K.length&&(y.source=z+K[1],z+=K[1],y.originalLine=n+K[2],n=y.originalLine,y.originalLine+=1,y.originalColumn=v+K[3],v=y.originalColumn,4<K.length&&(y.name=G+K[4],G+=K[4]));w.push(y);"number"===typeof y.originalLine&&h.push(y)}r(w,f.compareByGeneratedPositionsDeflated);this.__generatedMappings=w;r(h,f.compareByOriginalPositions);this.__originalMappings=h};p.prototype._findMapping=function(k,u,d,g,n,v){if(0>=k[d])throw new TypeError("Line must be greater than or equal to 1, got "+
|
||||
k[d]);if(0>k[g])throw new TypeError("Column must be greater than or equal to 0, got "+k[g]);return c.search(k,u,n,v)};p.prototype.computeColumnSpans=function(){for(var k=0;k<this._generatedMappings.length;++k){var u=this._generatedMappings[k];if(k+1<this._generatedMappings.length){var d=this._generatedMappings[k+1];if(u.generatedLine===d.generatedLine){u.lastGeneratedColumn=d.generatedColumn-1;continue}}u.lastGeneratedColumn=Infinity}};p.prototype.originalPositionFor=function(k){var u={generatedLine:f.getArg(k,
|
||||
"line"),generatedColumn:f.getArg(k,"column")};k=this._findMapping(u,this._generatedMappings,"generatedLine","generatedColumn",f.compareByGeneratedPositionsDeflated,f.getArg(k,"bias",e.GREATEST_LOWER_BOUND));if(0<=k&&(k=this._generatedMappings[k],k.generatedLine===u.generatedLine)){u=f.getArg(k,"source",null);null!==u&&(u=this._sources.at(u),u=f.computeSourceURL(this.sourceRoot,u,this._sourceMapURL));var d=f.getArg(k,"name",null);null!==d&&(d=this._names.at(d));return{source:u,line:f.getArg(k,"originalLine",
|
||||
null),column:f.getArg(k,"originalColumn",null),name:d}}return{source:null,line:null,column:null,name:null}};p.prototype.hasContentsOfAllSources=function(){return this.sourcesContent?this.sourcesContent.length>=this._sources.size()&&!this.sourcesContent.some(function(k){return null==k}):!1};p.prototype.sourceContentFor=function(k,u){if(!this.sourcesContent)return null;var d=k;null!=this.sourceRoot&&(d=f.relative(this.sourceRoot,d));if(this._sources.has(d))return this.sourcesContent[this._sources.indexOf(d)];
|
||||
var g=this.sources,n;for(n=0;n<g.length;++n)if(g[n]==k)return this.sourcesContent[n];var v;if(null!=this.sourceRoot&&(v=f.urlParse(this.sourceRoot))){g=d.replace(/^file:\/\//,"");if("file"==v.scheme&&this._sources.has(g))return this.sourcesContent[this._sources.indexOf(g)];if((!v.path||"/"==v.path)&&this._sources.has("/"+d))return this.sourcesContent[this._sources.indexOf("/"+d)]}if(u)return null;throw Error('"'+d+'" is not in the SourceMap.');};p.prototype.generatedPositionFor=function(k){var u=
|
||||
f.getArg(k,"source");null!=this.sourceRoot&&(u=f.relative(this.sourceRoot,u));if(!this._sources.has(u))return{line:null,column:null,lastColumn:null};u=this._sources.indexOf(u);u={source:u,originalLine:f.getArg(k,"line"),originalColumn:f.getArg(k,"column")};k=this._findMapping(u,this._originalMappings,"originalLine","originalColumn",f.compareByOriginalPositions,f.getArg(k,"bias",e.GREATEST_LOWER_BOUND));return 0<=k&&(k=this._originalMappings[k],k.source===u.source)?{line:f.getArg(k,"generatedLine",
|
||||
null),column:f.getArg(k,"generatedColumn",null),lastColumn:f.getArg(k,"lastGeneratedColumn",null)}:{line:null,column:null,lastColumn:null}};A.BasicSourceMapConsumer=p;m.prototype=Object.create(e.prototype);m.prototype.constructor=e;m.prototype._version=3;Object.defineProperty(m.prototype,"sources",{get:function(){for(var k=[],u=0;u<this._sections.length;u++)for(var d=0;d<this._sections[u].consumer.sources.length;d++)k.push(this._sections[u].consumer.sources[d]);return k}});m.prototype.originalPositionFor=
|
||||
function(k){var u={generatedLine:f.getArg(k,"line"),generatedColumn:f.getArg(k,"column")},d=c.search(u,this._sections,function(g,n){var v=g.generatedLine-n.generatedOffset.generatedLine;return v?v:g.generatedColumn-n.generatedOffset.generatedColumn});return(d=this._sections[d])?d.consumer.originalPositionFor({line:u.generatedLine-(d.generatedOffset.generatedLine-1),column:u.generatedColumn-(d.generatedOffset.generatedLine===u.generatedLine?d.generatedOffset.generatedColumn-1:0),bias:k.bias}):{source:null,
|
||||
line:null,column:null,name:null}};m.prototype.hasContentsOfAllSources=function(){return this._sections.every(function(k){return k.consumer.hasContentsOfAllSources()})};m.prototype.sourceContentFor=function(k,u){for(var d=0;d<this._sections.length;d++){var g=this._sections[d].consumer.sourceContentFor(k,!0);if(g)return g}if(u)return null;throw Error('"'+k+'" is not in the SourceMap.');};m.prototype.generatedPositionFor=function(k){for(var u=0;u<this._sections.length;u++){var d=this._sections[u];if(-1!==
|
||||
d.consumer.sources.indexOf(f.getArg(k,"source"))){var g=d.consumer.generatedPositionFor(k);if(g)return{line:g.line+(d.generatedOffset.generatedLine-1),column:g.column+(d.generatedOffset.generatedLine===g.line?d.generatedOffset.generatedColumn-1:0)}}}return{line:null,column:null}};m.prototype._parseMappings=function(k,u){this.__generatedMappings=[];this.__originalMappings=[];for(var d=0;d<this._sections.length;d++)for(var g=this._sections[d],n=g.consumer._generatedMappings,v=0;v<n.length;v++){var z=
|
||||
n[v],G=g.consumer._sources.at(z.source);G=f.computeSourceURL(g.consumer.sourceRoot,G,this._sourceMapURL);this._sources.add(G);G=this._sources.indexOf(G);var D=null;z.name&&(D=g.consumer._names.at(z.name),this._names.add(D),D=this._names.indexOf(D));z={source:G,generatedLine:z.generatedLine+(g.generatedOffset.generatedLine-1),generatedColumn:z.generatedColumn+(g.generatedOffset.generatedLine===z.generatedLine?g.generatedOffset.generatedColumn-1:0),originalLine:z.originalLine,originalColumn:z.originalColumn,
|
||||
name:D};this.__generatedMappings.push(z);"number"===typeof z.originalLine&&this.__originalMappings.push(z)}r(this.__generatedMappings,f.compareByGeneratedPositionsDeflated);r(this.__originalMappings,f.compareByOriginalPositions)};A.IndexedSourceMapConsumer=m},{"./array-set":10,"./base64-vlq":11,"./binary-search":13,"./quick-sort":15,"./util":19}],17:[function(C,J,A){function e(c){c||(c={});this._file=t.getArg(c,"file",null);this._sourceRoot=t.getArg(c,"sourceRoot",null);this._skipValidation=t.getArg(c,
|
||||
"skipValidation",!1);this._sources=new m;this._names=new m;this._mappings=new f;this._sourcesContents=null}var p=C("./base64-vlq"),t=C("./util"),m=C("./array-set").ArraySet,f=C("./mapping-list").MappingList;e.prototype._version=3;e.fromSourceMap=function(c){var l=c.sourceRoot,q=new e({file:c.file,sourceRoot:l});c.eachMapping(function(r){var k={generated:{line:r.generatedLine,column:r.generatedColumn}};null!=r.source&&(k.source=r.source,null!=l&&(k.source=t.relative(l,k.source)),k.original={line:r.originalLine,
|
||||
column:r.originalColumn},null!=r.name&&(k.name=r.name));q.addMapping(k)});c.sources.forEach(function(r){var k=r;null!==l&&(k=t.relative(l,r));q._sources.has(k)||q._sources.add(k);k=c.sourceContentFor(r);null!=k&&q.setSourceContent(r,k)});return q};e.prototype.addMapping=function(c){var l=t.getArg(c,"generated"),q=t.getArg(c,"original",null),r=t.getArg(c,"source",null);c=t.getArg(c,"name",null);this._skipValidation||this._validateMapping(l,q,r,c);null!=r&&(r=String(r),this._sources.has(r)||this._sources.add(r));
|
||||
null!=c&&(c=String(c),this._names.has(c)||this._names.add(c));this._mappings.add({generatedLine:l.line,generatedColumn:l.column,originalLine:null!=q&&q.line,originalColumn:null!=q&&q.column,source:r,name:c})};e.prototype.setSourceContent=function(c,l){var q=c;null!=this._sourceRoot&&(q=t.relative(this._sourceRoot,q));null!=l?(this._sourcesContents||(this._sourcesContents=Object.create(null)),this._sourcesContents[t.toSetString(q)]=l):this._sourcesContents&&(delete this._sourcesContents[t.toSetString(q)],
|
||||
0===Object.keys(this._sourcesContents).length&&(this._sourcesContents=null))};e.prototype.applySourceMap=function(c,l,q){var r=l;if(null==l){if(null==c.file)throw Error('SourceMapGenerator.prototype.applySourceMap requires either an explicit source file, or the source map\'s "file" property. Both were omitted.');r=c.file}var k=this._sourceRoot;null!=k&&(r=t.relative(k,r));var u=new m,d=new m;this._mappings.unsortedForEach(function(g){if(g.source===r&&null!=g.originalLine){var n=c.originalPositionFor({line:g.originalLine,
|
||||
column:g.originalColumn});null!=n.source&&(g.source=n.source,null!=q&&(g.source=t.join(q,g.source)),null!=k&&(g.source=t.relative(k,g.source)),g.originalLine=n.line,g.originalColumn=n.column,null!=n.name&&(g.name=n.name))}n=g.source;null==n||u.has(n)||u.add(n);g=g.name;null==g||d.has(g)||d.add(g)},this);this._sources=u;this._names=d;c.sources.forEach(function(g){var n=c.sourceContentFor(g);null!=n&&(null!=q&&(g=t.join(q,g)),null!=k&&(g=t.relative(k,g)),this.setSourceContent(g,n))},this)};e.prototype._validateMapping=
|
||||
function(c,l,q,r){if(l&&"number"!==typeof l.line&&"number"!==typeof l.column)throw Error("original.line and original.column are not numbers -- you probably meant to omit the original mapping entirely and only map the generated position. If so, pass null for the original mapping instead of an object with empty or null values.");if(!(c&&"line"in c&&"column"in c&&0<c.line&&0<=c.column&&!l&&!q&&!r||c&&"line"in c&&"column"in c&&l&&"line"in l&&"column"in l&&0<c.line&&0<=c.column&&0<l.line&&0<=l.column&&
|
||||
q))throw Error("Invalid mapping: "+JSON.stringify({generated:c,source:q,original:l,name:r}));};e.prototype._serializeMappings=function(){for(var c=0,l=1,q=0,r=0,k=0,u=0,d="",g,n,v,z=this._mappings.toArray(),G=0,D=z.length;G<D;G++){n=z[G];g="";if(n.generatedLine!==l)for(c=0;n.generatedLine!==l;)g+=";",l++;else if(0<G){if(!t.compareByGeneratedPositionsInflated(n,z[G-1]))continue;g+=","}g+=p.encode(n.generatedColumn-c);c=n.generatedColumn;null!=n.source&&(v=this._sources.indexOf(n.source),g+=p.encode(v-
|
||||
u),u=v,g+=p.encode(n.originalLine-1-r),r=n.originalLine-1,g+=p.encode(n.originalColumn-q),q=n.originalColumn,null!=n.name&&(n=this._names.indexOf(n.name),g+=p.encode(n-k),k=n));d+=g}return d};e.prototype._generateSourcesContent=function(c,l){return c.map(function(q){if(!this._sourcesContents)return null;null!=l&&(q=t.relative(l,q));q=t.toSetString(q);return Object.prototype.hasOwnProperty.call(this._sourcesContents,q)?this._sourcesContents[q]:null},this)};e.prototype.toJSON=function(){var c={version:this._version,
|
||||
sources:this._sources.toArray(),names:this._names.toArray(),mappings:this._serializeMappings()};null!=this._file&&(c.file=this._file);null!=this._sourceRoot&&(c.sourceRoot=this._sourceRoot);this._sourcesContents&&(c.sourcesContent=this._generateSourcesContent(c.sources,c.sourceRoot));return c};e.prototype.toString=function(){return JSON.stringify(this.toJSON())};A.SourceMapGenerator=e},{"./array-set":10,"./base64-vlq":11,"./mapping-list":14,"./util":19}],18:[function(C,J,A){function e(f,c,l,q,r){this.children=
|
||||
[];this.sourceContents={};this.line=null==f?null:f;this.column=null==c?null:c;this.source=null==l?null:l;this.name=null==r?null:r;this.$$$isSourceNode$$$=!0;null!=q&&this.add(q)}var p=C("./source-map-generator").SourceMapGenerator,t=C("./util"),m=/(\r?\n)/;e.fromStringWithSourceMap=function(f,c,l){function q(z,G){if(null===z||void 0===z.source)r.add(G);else{var D=l?t.join(l,z.source):z.source;r.add(new e(z.originalLine,z.originalColumn,D,G,z.name))}}var r=new e,k=f.split(m),u=0,d=function(){var z=
|
||||
u<k.length?k[u++]:void 0,G=(u<k.length?k[u++]:void 0)||"";return z+G},g=1,n=0,v=null;c.eachMapping(function(z){if(null!==v)if(g<z.generatedLine)q(v,d()),g++,n=0;else{var G=k[u]||"",D=G.substr(0,z.generatedColumn-n);k[u]=G.substr(z.generatedColumn-n);n=z.generatedColumn;q(v,D);v=z;return}for(;g<z.generatedLine;)r.add(d()),g++;n<z.generatedColumn&&(G=k[u]||"",r.add(G.substr(0,z.generatedColumn)),k[u]=G.substr(z.generatedColumn),n=z.generatedColumn);v=z},this);u<k.length&&(v&&q(v,d()),r.add(k.splice(u).join("")));
|
||||
c.sources.forEach(function(z){var G=c.sourceContentFor(z);null!=G&&(null!=l&&(z=t.join(l,z)),r.setSourceContent(z,G))});return r};e.prototype.add=function(f){if(Array.isArray(f))f.forEach(function(c){this.add(c)},this);else if(f.$$$isSourceNode$$$||"string"===typeof f)f&&this.children.push(f);else throw new TypeError("Expected a SourceNode, string, or an array of SourceNodes and strings. Got "+f);return this};e.prototype.prepend=function(f){if(Array.isArray(f))for(var c=f.length-1;0<=c;c--)this.prepend(f[c]);
|
||||
else if(f.$$$isSourceNode$$$||"string"===typeof f)this.children.unshift(f);else throw new TypeError("Expected a SourceNode, string, or an array of SourceNodes and strings. Got "+f);return this};e.prototype.walk=function(f){for(var c,l=0,q=this.children.length;l<q;l++)c=this.children[l],c.$$$isSourceNode$$$?c.walk(f):""!==c&&f(c,{source:this.source,line:this.line,column:this.column,name:this.name})};e.prototype.join=function(f){var c,l=this.children.length;if(0<l){var q=[];for(c=0;c<l-1;c++)q.push(this.children[c]),
|
||||
q.push(f);q.push(this.children[c]);this.children=q}return this};e.prototype.replaceRight=function(f,c){var l=this.children[this.children.length-1];l.$$$isSourceNode$$$?l.replaceRight(f,c):"string"===typeof l?this.children[this.children.length-1]=l.replace(f,c):this.children.push("".replace(f,c));return this};e.prototype.setSourceContent=function(f,c){this.sourceContents[t.toSetString(f)]=c};e.prototype.walkSourceContents=function(f){for(var c=0,l=this.children.length;c<l;c++)this.children[c].$$$isSourceNode$$$&&
|
||||
this.children[c].walkSourceContents(f);var q=Object.keys(this.sourceContents);c=0;for(l=q.length;c<l;c++)f(t.fromSetString(q[c]),this.sourceContents[q[c]])};e.prototype.toString=function(){var f="";this.walk(function(c){f+=c});return f};e.prototype.toStringWithSourceMap=function(f){var c="",l=1,q=0,r=new p(f),k=!1,u=null,d=null,g=null,n=null;this.walk(function(v,z){c+=v;null!==z.source&&null!==z.line&&null!==z.column?(u===z.source&&d===z.line&&g===z.column&&n===z.name||r.addMapping({source:z.source,
|
||||
original:{line:z.line,column:z.column},generated:{line:l,column:q},name:z.name}),u=z.source,d=z.line,g=z.column,n=z.name,k=!0):k&&(r.addMapping({generated:{line:l,column:q}}),u=null,k=!1);for(var G=0,D=v.length;G<D;G++)10===v.charCodeAt(G)?(l++,q=0,G+1===D?(u=null,k=!1):k&&r.addMapping({source:z.source,original:{line:z.line,column:z.column},generated:{line:l,column:q},name:z.name})):q++});this.walkSourceContents(function(v,z){r.setSourceContent(v,z)});return{code:c,map:r}};A.SourceNode=e},{"./source-map-generator":17,
|
||||
"./util":19}],19:[function(C,J,A){function e(d){return(d=d.match(k))?{scheme:d[1],auth:d[2],host:d[3],port:d[4],path:d[5]}:null}function p(d){var g="";d.scheme&&(g+=d.scheme+":");g+="//";d.auth&&(g+=d.auth+"@");d.host&&(g+=d.host);d.port&&(g+=":"+d.port);d.path&&(g+=d.path);return g}function t(d){var g=d,n=e(d);if(n){if(!n.path)return d;g=n.path}d=A.isAbsolute(g);g=g.split(/\/+/);for(var v,z=0,G=g.length-1;0<=G;G--)v=g[G],"."===v?g.splice(G,1):".."===v?z++:0<z&&(""===v?(g.splice(G+1,z),z=0):(g.splice(G,
|
||||
2),z--));g=g.join("/");""===g&&(g=d?"/":".");return n?(n.path=g,p(n)):g}function m(d,g){""===d&&(d=".");""===g&&(g=".");var n=e(g),v=e(d);v&&(d=v.path||"/");if(n&&!n.scheme)return v&&(n.scheme=v.scheme),p(n);if(n||g.match(u))return g;if(v&&!v.host&&!v.path)return v.host=g,p(v);n="/"===g.charAt(0)?g:t(d.replace(/\/+$/,"")+"/"+g);return v?(v.path=n,p(v)):n}function f(d){return d}function c(d){return q(d)?"$"+d:d}function l(d){return q(d)?d.slice(1):d}function q(d){if(!d)return!1;var g=d.length;if(9>
|
||||
g||95!==d.charCodeAt(g-1)||95!==d.charCodeAt(g-2)||111!==d.charCodeAt(g-3)||116!==d.charCodeAt(g-4)||111!==d.charCodeAt(g-5)||114!==d.charCodeAt(g-6)||112!==d.charCodeAt(g-7)||95!==d.charCodeAt(g-8)||95!==d.charCodeAt(g-9))return!1;for(g-=10;0<=g;g--)if(36!==d.charCodeAt(g))return!1;return!0}function r(d,g){return d===g?0:null===d?1:null===g?-1:d>g?1:-1}A.getArg=function(d,g,n){if(g in d)return d[g];if(3===arguments.length)return n;throw Error('"'+g+'" is a required argument.');};var k=/^(?:([\w+\-.]+):)?\/\/(?:(\w+:\w+)@)?([\w.-]*)(?::(\d+))?(.*)$/,
|
||||
u=/^data:.+,.+$/;A.urlParse=e;A.urlGenerate=p;A.normalize=t;A.join=m;A.isAbsolute=function(d){return"/"===d.charAt(0)||k.test(d)};A.relative=function(d,g){""===d&&(d=".");d=d.replace(/\/$/,"");for(var n=0;0!==g.indexOf(d+"/");){var v=d.lastIndexOf("/");if(0>v)return g;d=d.slice(0,v);if(d.match(/^([^\/]+:\/)?\/*$/))return g;++n}return Array(n+1).join("../")+g.substr(d.length+1)};C=!("__proto__"in Object.create(null));A.toSetString=C?f:c;A.fromSetString=C?f:l;A.compareByOriginalPositions=function(d,
|
||||
g,n){var v=r(d.source,g.source);if(0!==v)return v;v=d.originalLine-g.originalLine;if(0!==v)return v;v=d.originalColumn-g.originalColumn;if(0!==v||n)return v;v=d.generatedColumn-g.generatedColumn;if(0!==v)return v;v=d.generatedLine-g.generatedLine;return 0!==v?v:r(d.name,g.name)};A.compareByGeneratedPositionsDeflated=function(d,g,n){var v=d.generatedLine-g.generatedLine;if(0!==v)return v;v=d.generatedColumn-g.generatedColumn;if(0!==v||n)return v;v=r(d.source,g.source);if(0!==v)return v;v=d.originalLine-
|
||||
g.originalLine;if(0!==v)return v;v=d.originalColumn-g.originalColumn;return 0!==v?v:r(d.name,g.name)};A.compareByGeneratedPositionsInflated=function(d,g){var n=d.generatedLine-g.generatedLine;if(0!==n)return n;n=d.generatedColumn-g.generatedColumn;if(0!==n)return n;n=r(d.source,g.source);if(0!==n)return n;n=d.originalLine-g.originalLine;if(0!==n)return n;n=d.originalColumn-g.originalColumn;return 0!==n?n:r(d.name,g.name)};A.parseSourceMapInput=function(d){return JSON.parse(d.replace(/^\)]}'[^\n]*\n/,
|
||||
""))};A.computeSourceURL=function(d,g,n){g=g||"";d&&("/"!==d[d.length-1]&&"/"!==g[0]&&(d+="/"),g=d+g);if(n){d=e(n);if(!d)throw Error("sourceMapURL could not be parsed");d.path&&(n=d.path.lastIndexOf("/"),0<=n&&(d.path=d.path.substring(0,n+1)));g=m(p(d),g)}return t(g)}},{}],20:[function(C,J,A){A.SourceMapGenerator=C("./lib/source-map-generator").SourceMapGenerator;A.SourceMapConsumer=C("./lib/source-map-consumer").SourceMapConsumer;A.SourceNode=C("./lib/source-node").SourceNode},{"./lib/source-map-consumer":16,
|
||||
"./lib/source-map-generator":17,"./lib/source-node":18}],21:[function(C,J,A){(function(e){function p(){return"browser"===a?!0:"node"===a?!1:"undefined"!==typeof window&&"function"===typeof XMLHttpRequest&&!(window.require&&window.module&&window.process&&"renderer"===window.process.type)}function t(x){return function(B){for(var F=0;F<x.length;F++){var E=x[F](B);if(E)return E}return null}}function m(x,B){if(!x)return B;var F=n.dirname(x),E=/^\w+:\/\/[^\/]*/.exec(F);E=E?E[0]:"";var H=F.slice(E.length);
|
||||
return E&&/^\/\w:/.test(H)?(E+="/",E+n.resolve(F.slice(E.length),B).replace(/\\/g,"/")):E+n.resolve(F.slice(E.length),B)}function f(x){var B=h[x.source];if(!B){var F=N(x.source);F?(B=h[x.source]={url:F.url,map:new g(F.map)},B.map.sourcesContent&&B.map.sources.forEach(function(E,H){var M=B.map.sourcesContent[H];if(M){var S=m(B.url,E);b[S]=M}})):B=h[x.source]={url:null,map:null}}return B&&B.map&&"function"===typeof B.map.originalPositionFor&&(F=B.map.originalPositionFor(x),null!==F.source)?(F.source=
|
||||
m(B.url,F.source),F):x}function c(x){var B=/^eval at ([^(]+) \((.+):(\d+):(\d+)\)$/.exec(x);return B?(x=f({source:B[2],line:+B[3],column:B[4]-1}),"eval at "+B[1]+" ("+x.source+":"+x.line+":"+(x.column+1)+")"):(B=/^eval at ([^(]+) \((.+)\)$/.exec(x))?"eval at "+B[1]+" ("+c(B[2])+")":x}function l(){var x="";if(this.isNative())x="native";else{var B=this.getScriptNameOrSourceURL();!B&&this.isEval()&&(x=this.getEvalOrigin(),x+=", ");x=B?x+B:x+"<anonymous>";B=this.getLineNumber();null!=B&&(x+=":"+B,(B=
|
||||
this.getColumnNumber())&&(x+=":"+B))}B="";var F=this.getFunctionName(),E=!0,H=this.isConstructor();if(this.isToplevel()||H)H?B+="new "+(F||"<anonymous>"):F?B+=F:(B+=x,E=!1);else{H=this.getTypeName();"[object Object]"===H&&(H="null");var M=this.getMethodName();F?(H&&0!=F.indexOf(H)&&(B+=H+"."),B+=F,M&&F.indexOf("."+M)!=F.length-M.length-1&&(B+=" [as "+M+"]")):B+=H+"."+(M||"<anonymous>")}E&&(B+=" ("+x+")");return B}function q(x){var B={};Object.getOwnPropertyNames(Object.getPrototypeOf(x)).forEach(function(F){B[F]=
|
||||
/^(?:is|get)/.test(F)?function(){return x[F].call(x)}:x[F]});B.toString=l;return B}function r(x,B){void 0===B&&(B={nextPosition:null,curPosition:null});if(x.isNative())return B.curPosition=null,x;var F=x.getFileName()||x.getScriptNameOrSourceURL();if(F){var E=x.getLineNumber(),H=x.getColumnNumber()-1,M=/^v(10\.1[6-9]|10\.[2-9][0-9]|10\.[0-9]{3,}|1[2-9]\d*|[2-9]\d|\d{3,}|11\.11)/,S=M.test;var V="object"===typeof e&&null!==e?e.version:"";M=S.call(M,V)?0:62;1===E&&H>M&&!p()&&!x.isEval()&&(H-=M);var O=
|
||||
f({source:F,line:E,column:H});B.curPosition=O;x=q(x);var T=x.getFunctionName;x.getFunctionName=function(){return null==B.nextPosition?T():B.nextPosition.name||T()};x.getFileName=function(){return O.source};x.getLineNumber=function(){return O.line};x.getColumnNumber=function(){return O.column+1};x.getScriptNameOrSourceURL=function(){return O.source};return x}var Q=x.isEval()&&x.getEvalOrigin();Q&&(Q=c(Q),x=q(x),x.getEvalOrigin=function(){return Q});return x}function k(x,B){L&&(b={},h={});for(var F=
|
||||
(x.name||"Error")+": "+(x.message||""),E={nextPosition:null,curPosition:null},H=[],M=B.length-1;0<=M;M--)H.push("\n at "+r(B[M],E)),E.nextPosition=E.curPosition;E.curPosition=E.nextPosition=null;return F+H.reverse().join("")}function u(x){var B=/\n at [^(]+ \((.*):(\d+):(\d+)\)/.exec(x.stack);if(B){x=B[1];var F=+B[2];B=+B[3];var E=b[x];if(!E&&v&&v.existsSync(x))try{E=v.readFileSync(x,"utf8")}catch(H){E=""}if(E&&(E=E.split(/(?:\r\n|\r|\n)/)[F-1]))return x+":"+F+"\n"+E+"\n"+Array(B).join(" ")+
|
||||
"^"}return null}function d(){var x=e.emit;e.emit=function(B){if("uncaughtException"===B){var F=arguments[1]&&arguments[1].stack,E=0<this.listeners(B).length;if(F&&!E){F=arguments[1];E=u(F);var H="object"===typeof e&&null!==e?e.stderr:void 0;H&&H._handle&&H._handle.setBlocking&&H._handle.setBlocking(!0);E&&(console.error(),console.error(E));console.error(F.stack);"object"===typeof e&&null!==e&&"function"===typeof e.exit&&e.exit(1);return}}return x.apply(this,arguments)}}var g=C("source-map").SourceMapConsumer,
|
||||
n=C("path");try{var v=C("fs");v.existsSync&&v.readFileSync||(v=null)}catch(x){}var z=C("buffer-from"),G=!1,D=!1,L=!1,a="auto",b={},h={},w=/^data:application\/json[^,]+base64,/,y=[],I=[],K=t(y);y.push(function(x){x=x.trim();/^file:/.test(x)&&(x=x.replace(/file:\/\/\/(\w:)?/,function(E,H){return H?"":"/"}));if(x in b)return b[x];var B="";try{if(v)v.existsSync(x)&&(B=v.readFileSync(x,"utf8"));else{var F=new XMLHttpRequest;F.open("GET",x,!1);F.send(null);4===F.readyState&&200===F.status&&(B=F.responseText)}}catch(E){}return b[x]=
|
||||
B});var N=t(I);I.push(function(x){a:{if(p())try{var B=new XMLHttpRequest;B.open("GET",x,!1);B.send(null);var F=B.getResponseHeader("SourceMap")||B.getResponseHeader("X-SourceMap");if(F){var E=F;break a}}catch(M){}E=K(x);B=/(?:\/\/[@#][\s]*sourceMappingURL=([^\s'"]+)[\s]*$)|(?:\/\*[@#][\s]*sourceMappingURL=([^\s*'"]+)[\s]*(?:\*\/)[\s]*$)/mg;for(var H;F=B.exec(E);)H=F;E=H?H[1]:null}if(!E)return null;w.test(E)?(H=E.slice(E.indexOf(",")+1),H=z(H,"base64").toString(),E=x):(E=m(x,E),H=K(E));return H?{url:E,
|
||||
map:H}:null});var P=y.slice(0),W=I.slice(0);A.wrapCallSite=r;A.getErrorSource=u;A.mapSourcePosition=f;A.retrieveSourceMap=N;A.install=function(x){x=x||{};if(x.environment&&(a=x.environment,-1===["node","browser","auto"].indexOf(a)))throw Error("environment "+a+" was unknown. Available options are {auto, browser, node}");x.retrieveFile&&(x.overrideRetrieveFile&&(y.length=0),y.unshift(x.retrieveFile));x.retrieveSourceMap&&(x.overrideRetrieveSourceMap&&(I.length=0),I.unshift(x.retrieveSourceMap));if(x.hookRequire&&
|
||||
!p()){var B=J.require("module"),F=B.prototype._compile;F.__sourceMapSupport||(B.prototype._compile=function(E,H){b[H]=E;h[H]=void 0;return F.call(this,E,H)},B.prototype._compile.__sourceMapSupport=!0)}L||(L="emptyCacheBetweenOperations"in x?x.emptyCacheBetweenOperations:!1);G||(G=!0,Error.prepareStackTrace=k);if(!D){x="handleUncaughtExceptions"in x?x.handleUncaughtExceptions:!0;try{!1===J.require("worker_threads").isMainThread&&(x=!1)}catch(E){}x&&"object"===typeof e&&null!==e&&"function"===typeof e.on&&
|
||||
(D=!0,d())}};A.resetRetrieveHandlers=function(){y.length=0;I.length=0;y=P.slice(0);I=W.slice(0);N=t(I);K=t(y)}}).call(this,C("g5I+bs"))},{"buffer-from":4,fs:3,"g5I+bs":9,path:8,"source-map":20}]},{},[1]);return R});
|
||||
50
backend/node_modules/@cspotcode/source-map-support/package.json
generated
vendored
Normal file
50
backend/node_modules/@cspotcode/source-map-support/package.json
generated
vendored
Normal file
@ -0,0 +1,50 @@
|
||||
{
|
||||
"name": "@cspotcode/source-map-support",
|
||||
"description": "Fixes stack traces for files with source maps",
|
||||
"version": "0.8.1",
|
||||
"main": "./source-map-support.js",
|
||||
"types": "./source-map-support.d.ts",
|
||||
"scripts": {
|
||||
"build": "node build.js",
|
||||
"serve-tests": "http-server -p 1336",
|
||||
"test": "mocha"
|
||||
},
|
||||
"files": [
|
||||
"/register.d.ts",
|
||||
"/register.js",
|
||||
"/register-hook-require.d.ts",
|
||||
"/register-hook-require.js",
|
||||
"/source-map-support.d.ts",
|
||||
"/source-map-support.js",
|
||||
"/browser-source-map-support.js"
|
||||
],
|
||||
"dependencies": {
|
||||
"@jridgewell/trace-mapping": "0.3.9"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/lodash": "^4.14.182",
|
||||
"browserify": "^4.2.3",
|
||||
"coffeescript": "^1.12.7",
|
||||
"http-server": "^0.11.1",
|
||||
"lodash": "^4.17.21",
|
||||
"mocha": "^3.5.3",
|
||||
"semver": "^7.3.7",
|
||||
"source-map": "0.6.1",
|
||||
"webpack": "^1.15.0"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/cspotcode/node-source-map-support"
|
||||
},
|
||||
"bugs": {
|
||||
"url": "https://github.com/cspotcode/node-source-map-support/issues"
|
||||
},
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
},
|
||||
"volta": {
|
||||
"node": "16.11.0",
|
||||
"npm": "7.24.2"
|
||||
}
|
||||
}
|
||||
7
backend/node_modules/@cspotcode/source-map-support/register-hook-require.d.ts
generated
vendored
Executable file
7
backend/node_modules/@cspotcode/source-map-support/register-hook-require.d.ts
generated
vendored
Executable file
@ -0,0 +1,7 @@
|
||||
// tslint:disable:no-useless-files
|
||||
|
||||
// For following usage:
|
||||
// import '@cspotcode/source-map-support/register-hook-require'
|
||||
// Instead of:
|
||||
// import sourceMapSupport from '@cspotcode/source-map-support'
|
||||
// sourceMapSupport.install({hookRequire: true})
|
||||
3
backend/node_modules/@cspotcode/source-map-support/register-hook-require.js
generated
vendored
Normal file
3
backend/node_modules/@cspotcode/source-map-support/register-hook-require.js
generated
vendored
Normal file
@ -0,0 +1,3 @@
|
||||
require('./').install({
|
||||
hookRequire: true
|
||||
});
|
||||
7
backend/node_modules/@cspotcode/source-map-support/register.d.ts
generated
vendored
Executable file
7
backend/node_modules/@cspotcode/source-map-support/register.d.ts
generated
vendored
Executable file
@ -0,0 +1,7 @@
|
||||
// tslint:disable:no-useless-files
|
||||
|
||||
// For following usage:
|
||||
// import '@cspotcode/source-map-support/register'
|
||||
// Instead of:
|
||||
// import sourceMapSupport from '@cspotcode/source-map-support'
|
||||
// sourceMapSupport.install()
|
||||
1
backend/node_modules/@cspotcode/source-map-support/register.js
generated
vendored
Normal file
1
backend/node_modules/@cspotcode/source-map-support/register.js
generated
vendored
Normal file
@ -0,0 +1 @@
|
||||
require('./').install();
|
||||
76
backend/node_modules/@cspotcode/source-map-support/source-map-support.d.ts
generated
vendored
Executable file
76
backend/node_modules/@cspotcode/source-map-support/source-map-support.d.ts
generated
vendored
Executable file
@ -0,0 +1,76 @@
|
||||
// Type definitions for source-map-support 0.5
|
||||
// Project: https://github.com/evanw/node-source-map-support
|
||||
// Definitions by: Bart van der Schoor <https://github.com/Bartvds>
|
||||
// Jason Cheatham <https://github.com/jason0x43>
|
||||
// Alcedo Nathaniel De Guzman Jr <https://github.com/natealcedo>
|
||||
// Griffin Yourick <https://github.com/tough-griff>
|
||||
// Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped
|
||||
|
||||
export interface RawSourceMap {
|
||||
version: 3;
|
||||
sources: string[];
|
||||
names: string[];
|
||||
sourceRoot?: string;
|
||||
sourcesContent?: string[];
|
||||
mappings: string;
|
||||
file: string;
|
||||
}
|
||||
|
||||
/**
|
||||
* Output of retrieveSourceMap().
|
||||
* From source-map-support:
|
||||
* The map field may be either a string or the parsed JSON object (i.e.,
|
||||
* it must be a valid argument to the SourceMapConsumer constructor).
|
||||
*/
|
||||
export interface UrlAndMap {
|
||||
url: string;
|
||||
map: string | RawSourceMap;
|
||||
}
|
||||
|
||||
/**
|
||||
* Options to install().
|
||||
*/
|
||||
export interface Options {
|
||||
handleUncaughtExceptions?: boolean | undefined;
|
||||
hookRequire?: boolean | undefined;
|
||||
emptyCacheBetweenOperations?: boolean | undefined;
|
||||
environment?: 'auto' | 'browser' | 'node' | undefined;
|
||||
overrideRetrieveFile?: boolean | undefined;
|
||||
overrideRetrieveSourceMap?: boolean | undefined;
|
||||
retrieveFile?(path: string): string;
|
||||
retrieveSourceMap?(source: string): UrlAndMap | null;
|
||||
/**
|
||||
* Set false to disable redirection of require / import `source-map-support` to `@cspotcode/source-map-support`
|
||||
*/
|
||||
redirectConflictingLibrary?: boolean;
|
||||
/**
|
||||
* Callback will be called every time we redirect due to `redirectConflictingLibrary`
|
||||
* This allows consumers to log helpful warnings if they choose.
|
||||
* @param parent NodeJS.Module which made the require() or require.resolve() call
|
||||
* @param options options object internally passed to node's `_resolveFilename` hook
|
||||
*/
|
||||
onConflictingLibraryRedirect?: (request: string, parent: any, isMain: boolean, options: any, redirectedRequest: string) => void;
|
||||
}
|
||||
|
||||
export interface Position {
|
||||
source: string;
|
||||
line: number;
|
||||
column: number;
|
||||
}
|
||||
|
||||
export function wrapCallSite(frame: any /* StackFrame */): any /* StackFrame */;
|
||||
export function getErrorSource(error: Error): string | null;
|
||||
export function mapSourcePosition(position: Position): Position;
|
||||
export function retrieveSourceMap(source: string): UrlAndMap | null;
|
||||
export function resetRetrieveHandlers(): void;
|
||||
|
||||
/**
|
||||
* Install SourceMap support.
|
||||
* @param options Can be used to e.g. disable uncaughtException handler.
|
||||
*/
|
||||
export function install(options?: Options): void;
|
||||
|
||||
/**
|
||||
* Uninstall SourceMap support.
|
||||
*/
|
||||
export function uninstall(): void;
|
||||
938
backend/node_modules/@cspotcode/source-map-support/source-map-support.js
generated
vendored
Normal file
938
backend/node_modules/@cspotcode/source-map-support/source-map-support.js
generated
vendored
Normal file
@ -0,0 +1,938 @@
|
||||
const { TraceMap, originalPositionFor, AnyMap } = require('@jridgewell/trace-mapping');
|
||||
var path = require('path');
|
||||
const { fileURLToPath, pathToFileURL } = require('url');
|
||||
var util = require('util');
|
||||
|
||||
var fs;
|
||||
try {
|
||||
fs = require('fs');
|
||||
if (!fs.existsSync || !fs.readFileSync) {
|
||||
// fs doesn't have all methods we need
|
||||
fs = null;
|
||||
}
|
||||
} catch (err) {
|
||||
/* nop */
|
||||
}
|
||||
|
||||
/**
|
||||
* Requires a module which is protected against bundler minification.
|
||||
*
|
||||
* @param {NodeModule} mod
|
||||
* @param {string} request
|
||||
*/
|
||||
function dynamicRequire(mod, request) {
|
||||
return mod.require(request);
|
||||
}
|
||||
|
||||
/**
|
||||
* @typedef {{
|
||||
* enabled: boolean;
|
||||
* originalValue: any;
|
||||
* installedValue: any;
|
||||
* }} HookState
|
||||
* Used for installing and uninstalling hooks
|
||||
*/
|
||||
|
||||
// Increment this if the format of sharedData changes in a breaking way.
|
||||
var sharedDataVersion = 1;
|
||||
|
||||
/**
|
||||
* @template T
|
||||
* @param {T} defaults
|
||||
* @returns {T}
|
||||
*/
|
||||
function initializeSharedData(defaults) {
|
||||
var sharedDataKey = 'source-map-support/sharedData';
|
||||
if (typeof Symbol !== 'undefined') {
|
||||
sharedDataKey = Symbol.for(sharedDataKey);
|
||||
}
|
||||
var sharedData = this[sharedDataKey];
|
||||
if (!sharedData) {
|
||||
sharedData = { version: sharedDataVersion };
|
||||
if (Object.defineProperty) {
|
||||
Object.defineProperty(this, sharedDataKey, { value: sharedData });
|
||||
} else {
|
||||
this[sharedDataKey] = sharedData;
|
||||
}
|
||||
}
|
||||
if (sharedDataVersion !== sharedData.version) {
|
||||
throw new Error("Multiple incompatible instances of source-map-support were loaded");
|
||||
}
|
||||
for (var key in defaults) {
|
||||
if (!(key in sharedData)) {
|
||||
sharedData[key] = defaults[key];
|
||||
}
|
||||
}
|
||||
return sharedData;
|
||||
}
|
||||
|
||||
// If multiple instances of source-map-support are loaded into the same
|
||||
// context, they shouldn't overwrite each other. By storing handlers, caches,
|
||||
// and other state on a shared object, different instances of
|
||||
// source-map-support can work together in a limited way. This does require
|
||||
// that future versions of source-map-support continue to support the fields on
|
||||
// this object. If this internal contract ever needs to be broken, increment
|
||||
// sharedDataVersion. (This version number is not the same as any of the
|
||||
// package's version numbers, which should reflect the *external* API of
|
||||
// source-map-support.)
|
||||
var sharedData = initializeSharedData({
|
||||
|
||||
// Only install once if called multiple times
|
||||
// Remember how the environment looked before installation so we can restore if able
|
||||
/** @type {HookState} */
|
||||
errorPrepareStackTraceHook: undefined,
|
||||
/** @type {HookState} */
|
||||
processEmitHook: undefined,
|
||||
/** @type {HookState} */
|
||||
moduleResolveFilenameHook: undefined,
|
||||
|
||||
/** @type {Array<(request: string, parent: any, isMain: boolean, options: any, redirectedRequest: string) => void>} */
|
||||
onConflictingLibraryRedirectArr: [],
|
||||
|
||||
// If true, the caches are reset before a stack trace formatting operation
|
||||
emptyCacheBetweenOperations: false,
|
||||
|
||||
// Maps a file path to a string containing the file contents
|
||||
fileContentsCache: Object.create(null),
|
||||
|
||||
// Maps a file path to a source map for that file
|
||||
/** @type {Record<string, {url: string, map: TraceMap}} */
|
||||
sourceMapCache: Object.create(null),
|
||||
|
||||
// Priority list of retrieve handlers
|
||||
retrieveFileHandlers: [],
|
||||
retrieveMapHandlers: [],
|
||||
|
||||
// Priority list of internally-implemented handlers.
|
||||
// When resetting state, we must keep these.
|
||||
internalRetrieveFileHandlers: [],
|
||||
internalRetrieveMapHandlers: [],
|
||||
|
||||
});
|
||||
|
||||
// Supports {browser, node, auto}
|
||||
var environment = "auto";
|
||||
|
||||
// Regex for detecting source maps
|
||||
var reSourceMap = /^data:application\/json[^,]+base64,/;
|
||||
|
||||
function isInBrowser() {
|
||||
if (environment === "browser")
|
||||
return true;
|
||||
if (environment === "node")
|
||||
return false;
|
||||
return ((typeof window !== 'undefined') && (typeof XMLHttpRequest === 'function') && !(window.require && window.module && window.process && window.process.type === "renderer"));
|
||||
}
|
||||
|
||||
function hasGlobalProcessEventEmitter() {
|
||||
return ((typeof process === 'object') && (process !== null) && (typeof process.on === 'function'));
|
||||
}
|
||||
|
||||
function tryFileURLToPath(v) {
|
||||
if(isFileUrl(v)) {
|
||||
return fileURLToPath(v);
|
||||
}
|
||||
return v;
|
||||
}
|
||||
|
||||
// TODO un-copy these from resolve-uri; see if they can be exported from that lib
|
||||
function isFileUrl(input) {
|
||||
return input.startsWith('file:');
|
||||
}
|
||||
function isAbsoluteUrl(input) {
|
||||
return schemeRegex.test(input);
|
||||
}
|
||||
// Matches the scheme of a URL, eg "http://"
|
||||
const schemeRegex = /^[\w+.-]+:\/\//;
|
||||
function isSchemeRelativeUrl(input) {
|
||||
return input.startsWith('//');
|
||||
}
|
||||
|
||||
// #region Caches
|
||||
/** @param {string} pathOrFileUrl */
|
||||
function getCacheKey(pathOrFileUrl) {
|
||||
if(pathOrFileUrl.startsWith('node:')) return pathOrFileUrl;
|
||||
if(isFileUrl(pathOrFileUrl)) {
|
||||
// Must normalize spaces to %20, stuff like that
|
||||
return new URL(pathOrFileUrl).toString();
|
||||
} else {
|
||||
try {
|
||||
return pathToFileURL(pathOrFileUrl).toString();
|
||||
} catch {
|
||||
return pathOrFileUrl;
|
||||
}
|
||||
}
|
||||
}
|
||||
function getFileContentsCache(key) {
|
||||
return sharedData.fileContentsCache[getCacheKey(key)];
|
||||
}
|
||||
function hasFileContentsCacheFromKey(key) {
|
||||
return Object.prototype.hasOwnProperty.call(sharedData.fileContentsCache, key);
|
||||
}
|
||||
function getFileContentsCacheFromKey(key) {
|
||||
return sharedData.fileContentsCache[key];
|
||||
}
|
||||
function setFileContentsCache(key, value) {
|
||||
return sharedData.fileContentsCache[getCacheKey(key)] = value;
|
||||
}
|
||||
function getSourceMapCache(key) {
|
||||
return sharedData.sourceMapCache[getCacheKey(key)];
|
||||
}
|
||||
function setSourceMapCache(key, value) {
|
||||
return sharedData.sourceMapCache[getCacheKey(key)] = value;
|
||||
}
|
||||
function clearCaches() {
|
||||
sharedData.fileContentsCache = Object.create(null);
|
||||
sharedData.sourceMapCache = Object.create(null);
|
||||
}
|
||||
// #endregion Caches
|
||||
|
||||
function handlerExec(list, internalList) {
|
||||
return function(arg) {
|
||||
for (var i = 0; i < list.length; i++) {
|
||||
var ret = list[i](arg);
|
||||
if (ret) {
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
for (var i = 0; i < internalList.length; i++) {
|
||||
var ret = internalList[i](arg);
|
||||
if (ret) {
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
};
|
||||
}
|
||||
|
||||
var retrieveFile = handlerExec(sharedData.retrieveFileHandlers, sharedData.internalRetrieveFileHandlers);
|
||||
|
||||
sharedData.internalRetrieveFileHandlers.push(function(path) {
|
||||
// Trim the path to make sure there is no extra whitespace.
|
||||
path = path.trim();
|
||||
if (/^file:/.test(path)) {
|
||||
// existsSync/readFileSync can't handle file protocol, but once stripped, it works
|
||||
path = path.replace(/file:\/\/\/(\w:)?/, function(protocol, drive) {
|
||||
return drive ?
|
||||
'' : // file:///C:/dir/file -> C:/dir/file
|
||||
'/'; // file:///root-dir/file -> /root-dir/file
|
||||
});
|
||||
}
|
||||
const key = getCacheKey(path);
|
||||
if(hasFileContentsCacheFromKey(key)) {
|
||||
return getFileContentsCacheFromKey(key);
|
||||
}
|
||||
|
||||
var contents = '';
|
||||
try {
|
||||
if (!fs) {
|
||||
// Use SJAX if we are in the browser
|
||||
var xhr = new XMLHttpRequest();
|
||||
xhr.open('GET', path, /** async */ false);
|
||||
xhr.send(null);
|
||||
if (xhr.readyState === 4 && xhr.status === 200) {
|
||||
contents = xhr.responseText;
|
||||
}
|
||||
} else if (fs.existsSync(path)) {
|
||||
// Otherwise, use the filesystem
|
||||
contents = fs.readFileSync(path, 'utf8');
|
||||
}
|
||||
} catch (er) {
|
||||
/* ignore any errors */
|
||||
}
|
||||
|
||||
return setFileContentsCache(path, contents);
|
||||
});
|
||||
|
||||
// Support URLs relative to a directory, but be careful about a protocol prefix
|
||||
// in case we are in the browser (i.e. directories may start with "http://" or "file:///")
|
||||
function supportRelativeURL(file, url) {
|
||||
if(!file) return url;
|
||||
// given that this happens within error formatting codepath, probably best to
|
||||
// fallback instead of throwing if anything goes wrong
|
||||
try {
|
||||
// if should output a URL
|
||||
if(isAbsoluteUrl(file) || isSchemeRelativeUrl(file)) {
|
||||
if(isAbsoluteUrl(url) || isSchemeRelativeUrl(url)) {
|
||||
return new URL(url, file).toString();
|
||||
}
|
||||
if(path.isAbsolute(url)) {
|
||||
return new URL(pathToFileURL(url), file).toString();
|
||||
}
|
||||
// url is relative path or URL
|
||||
return new URL(url.replace(/\\/g, '/'), file).toString();
|
||||
}
|
||||
// if should output a path (unless URL is something like https://)
|
||||
if(path.isAbsolute(file)) {
|
||||
if(isFileUrl(url)) {
|
||||
return fileURLToPath(url);
|
||||
}
|
||||
if(isSchemeRelativeUrl(url)) {
|
||||
return fileURLToPath(new URL(url, 'file://'));
|
||||
}
|
||||
if(isAbsoluteUrl(url)) {
|
||||
// url is a non-file URL
|
||||
// Go with the URL
|
||||
return url;
|
||||
}
|
||||
if(path.isAbsolute(url)) {
|
||||
// Normalize at all? decodeURI or normalize slashes?
|
||||
return path.normalize(url);
|
||||
}
|
||||
// url is relative path or URL
|
||||
return path.join(file, '..', decodeURI(url));
|
||||
}
|
||||
// If we get here, file is relative.
|
||||
// Shouldn't happen since node identifies modules with absolute paths or URLs.
|
||||
// But we can take a stab at returning something meaningful anyway.
|
||||
if(isAbsoluteUrl(url) || isSchemeRelativeUrl(url)) {
|
||||
return url;
|
||||
}
|
||||
return path.join(file, '..', url);
|
||||
} catch(e) {
|
||||
return url;
|
||||
}
|
||||
}
|
||||
|
||||
// Return pathOrUrl in the same style as matchStyleOf: either a file URL or a native path
|
||||
function matchStyleOfPathOrUrl(matchStyleOf, pathOrUrl) {
|
||||
try {
|
||||
if(isAbsoluteUrl(matchStyleOf) || isSchemeRelativeUrl(matchStyleOf)) {
|
||||
if(isAbsoluteUrl(pathOrUrl) || isSchemeRelativeUrl(pathOrUrl)) return pathOrUrl;
|
||||
if(path.isAbsolute(pathOrUrl)) return pathToFileURL(pathOrUrl).toString();
|
||||
} else if(path.isAbsolute(matchStyleOf)) {
|
||||
if(isAbsoluteUrl(pathOrUrl) || isSchemeRelativeUrl(pathOrUrl)) {
|
||||
return fileURLToPath(new URL(pathOrUrl, 'file://'));
|
||||
}
|
||||
}
|
||||
return pathOrUrl;
|
||||
} catch(e) {
|
||||
return pathOrUrl;
|
||||
}
|
||||
}
|
||||
|
||||
function retrieveSourceMapURL(source) {
|
||||
var fileData;
|
||||
|
||||
if (isInBrowser()) {
|
||||
try {
|
||||
var xhr = new XMLHttpRequest();
|
||||
xhr.open('GET', source, false);
|
||||
xhr.send(null);
|
||||
fileData = xhr.readyState === 4 ? xhr.responseText : null;
|
||||
|
||||
// Support providing a sourceMappingURL via the SourceMap header
|
||||
var sourceMapHeader = xhr.getResponseHeader("SourceMap") ||
|
||||
xhr.getResponseHeader("X-SourceMap");
|
||||
if (sourceMapHeader) {
|
||||
return sourceMapHeader;
|
||||
}
|
||||
} catch (e) {
|
||||
}
|
||||
}
|
||||
|
||||
// Get the URL of the source map
|
||||
fileData = retrieveFile(tryFileURLToPath(source));
|
||||
var re = /(?:\/\/[@#][\s]*sourceMappingURL=([^\s'"]+)[\s]*$)|(?:\/\*[@#][\s]*sourceMappingURL=([^\s*'"]+)[\s]*(?:\*\/)[\s]*$)/mg;
|
||||
// Keep executing the search to find the *last* sourceMappingURL to avoid
|
||||
// picking up sourceMappingURLs from comments, strings, etc.
|
||||
var lastMatch, match;
|
||||
while (match = re.exec(fileData)) lastMatch = match;
|
||||
if (!lastMatch) return null;
|
||||
return lastMatch[1];
|
||||
};
|
||||
|
||||
// Can be overridden by the retrieveSourceMap option to install. Takes a
|
||||
// generated source filename; returns a {map, optional url} object, or null if
|
||||
// there is no source map. The map field may be either a string or the parsed
|
||||
// JSON object (ie, it must be a valid argument to the SourceMapConsumer
|
||||
// constructor).
|
||||
/** @type {(source: string) => import('./source-map-support').UrlAndMap | null} */
|
||||
var retrieveSourceMap = handlerExec(sharedData.retrieveMapHandlers, sharedData.internalRetrieveMapHandlers);
|
||||
sharedData.internalRetrieveMapHandlers.push(function(source) {
|
||||
var sourceMappingURL = retrieveSourceMapURL(source);
|
||||
if (!sourceMappingURL) return null;
|
||||
|
||||
// Read the contents of the source map
|
||||
var sourceMapData;
|
||||
if (reSourceMap.test(sourceMappingURL)) {
|
||||
// Support source map URL as a data url
|
||||
var rawData = sourceMappingURL.slice(sourceMappingURL.indexOf(',') + 1);
|
||||
sourceMapData = Buffer.from(rawData, "base64").toString();
|
||||
sourceMappingURL = source;
|
||||
} else {
|
||||
// Support source map URLs relative to the source URL
|
||||
sourceMappingURL = supportRelativeURL(source, sourceMappingURL);
|
||||
sourceMapData = retrieveFile(tryFileURLToPath(sourceMappingURL));
|
||||
}
|
||||
|
||||
if (!sourceMapData) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return {
|
||||
url: sourceMappingURL,
|
||||
map: sourceMapData
|
||||
};
|
||||
});
|
||||
|
||||
function mapSourcePosition(position) {
|
||||
var sourceMap = getSourceMapCache(position.source);
|
||||
if (!sourceMap) {
|
||||
// Call the (overrideable) retrieveSourceMap function to get the source map.
|
||||
var urlAndMap = retrieveSourceMap(position.source);
|
||||
if (urlAndMap) {
|
||||
sourceMap = setSourceMapCache(position.source, {
|
||||
url: urlAndMap.url,
|
||||
map: new AnyMap(urlAndMap.map, urlAndMap.url)
|
||||
});
|
||||
|
||||
// Overwrite trace-mapping's resolutions, because they do not handle
|
||||
// Windows paths the way we want.
|
||||
// TODO Remove now that windows path support was added to resolve-uri and thus trace-mapping?
|
||||
sourceMap.map.resolvedSources = sourceMap.map.sources.map(s => supportRelativeURL(sourceMap.url, s));
|
||||
|
||||
// Load all sources stored inline with the source map into the file cache
|
||||
// to pretend like they are already loaded. They may not exist on disk.
|
||||
if (sourceMap.map.sourcesContent) {
|
||||
sourceMap.map.resolvedSources.forEach(function(resolvedSource, i) {
|
||||
var contents = sourceMap.map.sourcesContent[i];
|
||||
if (contents) {
|
||||
setFileContentsCache(resolvedSource, contents);
|
||||
}
|
||||
});
|
||||
}
|
||||
} else {
|
||||
sourceMap = setSourceMapCache(position.source, {
|
||||
url: null,
|
||||
map: null
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// Resolve the source URL relative to the URL of the source map
|
||||
if (sourceMap && sourceMap.map) {
|
||||
var originalPosition = originalPositionFor(sourceMap.map, position);
|
||||
|
||||
// Only return the original position if a matching line was found. If no
|
||||
// matching line is found then we return position instead, which will cause
|
||||
// the stack trace to print the path and line for the compiled file. It is
|
||||
// better to give a precise location in the compiled file than a vague
|
||||
// location in the original file.
|
||||
if (originalPosition.source !== null) {
|
||||
// originalPosition.source has *already* been resolved against sourceMap.url
|
||||
// so is *already* as absolute as possible.
|
||||
// However, we want to ensure we output in same format as input: URL or native path
|
||||
originalPosition.source = matchStyleOfPathOrUrl(
|
||||
position.source, originalPosition.source);
|
||||
return originalPosition;
|
||||
}
|
||||
}
|
||||
|
||||
return position;
|
||||
}
|
||||
|
||||
// Parses code generated by FormatEvalOrigin(), a function inside V8:
|
||||
// https://code.google.com/p/v8/source/browse/trunk/src/messages.js
|
||||
function mapEvalOrigin(origin) {
|
||||
// Most eval() calls are in this format
|
||||
var match = /^eval at ([^(]+) \((.+):(\d+):(\d+)\)$/.exec(origin);
|
||||
if (match) {
|
||||
var position = mapSourcePosition({
|
||||
source: match[2],
|
||||
line: +match[3],
|
||||
column: match[4] - 1
|
||||
});
|
||||
return 'eval at ' + match[1] + ' (' + position.source + ':' +
|
||||
position.line + ':' + (position.column + 1) + ')';
|
||||
}
|
||||
|
||||
// Parse nested eval() calls using recursion
|
||||
match = /^eval at ([^(]+) \((.+)\)$/.exec(origin);
|
||||
if (match) {
|
||||
return 'eval at ' + match[1] + ' (' + mapEvalOrigin(match[2]) + ')';
|
||||
}
|
||||
|
||||
// Make sure we still return useful information if we didn't find anything
|
||||
return origin;
|
||||
}
|
||||
|
||||
// This is copied almost verbatim from the V8 source code at
|
||||
// https://code.google.com/p/v8/source/browse/trunk/src/messages.js
|
||||
// Update 2022-04-29:
|
||||
// https://github.com/v8/v8/blob/98f6f100c5ab8e390e51422747c4ef644d5ac6f2/src/builtins/builtins-callsite.cc#L175-L179
|
||||
// https://github.com/v8/v8/blob/98f6f100c5ab8e390e51422747c4ef644d5ac6f2/src/objects/call-site-info.cc#L795-L804
|
||||
// https://github.com/v8/v8/blob/98f6f100c5ab8e390e51422747c4ef644d5ac6f2/src/objects/call-site-info.cc#L717-L750
|
||||
// The implementation of wrapCallSite() used to just forward to the actual source
|
||||
// code of CallSite.prototype.toString but unfortunately a new release of V8
|
||||
// did something to the prototype chain and broke the shim. The only fix I
|
||||
// could find was copy/paste.
|
||||
function CallSiteToString() {
|
||||
var fileName;
|
||||
var fileLocation = "";
|
||||
if (this.isNative()) {
|
||||
fileLocation = "native";
|
||||
} else {
|
||||
fileName = this.getScriptNameOrSourceURL();
|
||||
if (!fileName && this.isEval()) {
|
||||
fileLocation = this.getEvalOrigin();
|
||||
fileLocation += ", "; // Expecting source position to follow.
|
||||
}
|
||||
|
||||
if (fileName) {
|
||||
fileLocation += fileName;
|
||||
} else {
|
||||
// Source code does not originate from a file and is not native, but we
|
||||
// can still get the source position inside the source string, e.g. in
|
||||
// an eval string.
|
||||
fileLocation += "<anonymous>";
|
||||
}
|
||||
var lineNumber = this.getLineNumber();
|
||||
if (lineNumber != null) {
|
||||
fileLocation += ":" + lineNumber;
|
||||
var columnNumber = this.getColumnNumber();
|
||||
if (columnNumber) {
|
||||
fileLocation += ":" + columnNumber;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var line = "";
|
||||
var isAsync = this.isAsync ? this.isAsync() : false;
|
||||
if(isAsync) {
|
||||
line += 'async ';
|
||||
var isPromiseAll = this.isPromiseAll ? this.isPromiseAll() : false;
|
||||
var isPromiseAny = this.isPromiseAny ? this.isPromiseAny() : false;
|
||||
if(isPromiseAny || isPromiseAll) {
|
||||
line += isPromiseAll ? 'Promise.all (index ' : 'Promise.any (index ';
|
||||
var promiseIndex = this.getPromiseIndex();
|
||||
line += promiseIndex + ')';
|
||||
}
|
||||
}
|
||||
var functionName = this.getFunctionName();
|
||||
var addSuffix = true;
|
||||
var isConstructor = this.isConstructor();
|
||||
var isMethodCall = !(this.isToplevel() || isConstructor);
|
||||
if (isMethodCall) {
|
||||
var typeName = this.getTypeName();
|
||||
// Fixes shim to be backward compatable with Node v0 to v4
|
||||
if (typeName === "[object Object]") {
|
||||
typeName = "null";
|
||||
}
|
||||
var methodName = this.getMethodName();
|
||||
if (functionName) {
|
||||
if (typeName && functionName.indexOf(typeName) != 0) {
|
||||
line += typeName + ".";
|
||||
}
|
||||
line += functionName;
|
||||
if (methodName && functionName.indexOf("." + methodName) != functionName.length - methodName.length - 1) {
|
||||
line += " [as " + methodName + "]";
|
||||
}
|
||||
} else {
|
||||
line += typeName + "." + (methodName || "<anonymous>");
|
||||
}
|
||||
} else if (isConstructor) {
|
||||
line += "new " + (functionName || "<anonymous>");
|
||||
} else if (functionName) {
|
||||
line += functionName;
|
||||
} else {
|
||||
line += fileLocation;
|
||||
addSuffix = false;
|
||||
}
|
||||
if (addSuffix) {
|
||||
line += " (" + fileLocation + ")";
|
||||
}
|
||||
return line;
|
||||
}
|
||||
|
||||
function cloneCallSite(frame) {
|
||||
var object = {};
|
||||
Object.getOwnPropertyNames(Object.getPrototypeOf(frame)).forEach(function(name) {
|
||||
object[name] = /^(?:is|get)/.test(name) ? function() { return frame[name].call(frame); } : frame[name];
|
||||
});
|
||||
object.toString = CallSiteToString;
|
||||
return object;
|
||||
}
|
||||
|
||||
function wrapCallSite(frame, state) {
|
||||
// provides interface backward compatibility
|
||||
if (state === undefined) {
|
||||
state = { nextPosition: null, curPosition: null }
|
||||
}
|
||||
if(frame.isNative()) {
|
||||
state.curPosition = null;
|
||||
return frame;
|
||||
}
|
||||
|
||||
// Most call sites will return the source file from getFileName(), but code
|
||||
// passed to eval() ending in "//# sourceURL=..." will return the source file
|
||||
// from getScriptNameOrSourceURL() instead
|
||||
var source = frame.getFileName() || frame.getScriptNameOrSourceURL();
|
||||
if (source) {
|
||||
// v8 does not expose its internal isWasm, etc methods, so we do this instead.
|
||||
if(source.startsWith('wasm://')) {
|
||||
state.curPosition = null;
|
||||
return frame;
|
||||
}
|
||||
|
||||
var line = frame.getLineNumber();
|
||||
var column = frame.getColumnNumber() - 1;
|
||||
|
||||
// Fix position in Node where some (internal) code is prepended.
|
||||
// See https://github.com/evanw/node-source-map-support/issues/36
|
||||
// Header removed in node at ^10.16 || >=11.11.0
|
||||
// v11 is not an LTS candidate, we can just test the one version with it.
|
||||
// Test node versions for: 10.16-19, 10.20+, 12-19, 20-99, 100+, or 11.11
|
||||
var noHeader = /^v(10\.1[6-9]|10\.[2-9][0-9]|10\.[0-9]{3,}|1[2-9]\d*|[2-9]\d|\d{3,}|11\.11)/;
|
||||
var headerLength = noHeader.test(process.version) ? 0 : 62;
|
||||
if (line === 1 && column > headerLength && !isInBrowser() && !frame.isEval()) {
|
||||
column -= headerLength;
|
||||
}
|
||||
|
||||
var position = mapSourcePosition({
|
||||
source: source,
|
||||
line: line,
|
||||
column: column
|
||||
});
|
||||
state.curPosition = position;
|
||||
frame = cloneCallSite(frame);
|
||||
var originalFunctionName = frame.getFunctionName;
|
||||
frame.getFunctionName = function() {
|
||||
if (state.nextPosition == null) {
|
||||
return originalFunctionName();
|
||||
}
|
||||
return state.nextPosition.name || originalFunctionName();
|
||||
};
|
||||
frame.getFileName = function() { return position.source; };
|
||||
frame.getLineNumber = function() { return position.line; };
|
||||
frame.getColumnNumber = function() { return position.column + 1; };
|
||||
frame.getScriptNameOrSourceURL = function() { return position.source; };
|
||||
return frame;
|
||||
}
|
||||
|
||||
// Code called using eval() needs special handling
|
||||
var origin = frame.isEval() && frame.getEvalOrigin();
|
||||
if (origin) {
|
||||
origin = mapEvalOrigin(origin);
|
||||
frame = cloneCallSite(frame);
|
||||
frame.getEvalOrigin = function() { return origin; };
|
||||
return frame;
|
||||
}
|
||||
|
||||
// If we get here then we were unable to change the source position
|
||||
return frame;
|
||||
}
|
||||
|
||||
var kIsNodeError = undefined;
|
||||
try {
|
||||
// Get a deliberate ERR_INVALID_ARG_TYPE
|
||||
// TODO is there a better way to reliably get an instance of NodeError?
|
||||
path.resolve(123);
|
||||
} catch(e) {
|
||||
const symbols = Object.getOwnPropertySymbols(e);
|
||||
const symbol = symbols.find(function (s) {return s.toString().indexOf('kIsNodeError') >= 0});
|
||||
if(symbol) kIsNodeError = symbol;
|
||||
}
|
||||
|
||||
const ErrorPrototypeToString = (err) =>Error.prototype.toString.call(err);
|
||||
|
||||
/** @param {HookState} hookState */
|
||||
function createPrepareStackTrace(hookState) {
|
||||
return prepareStackTrace;
|
||||
|
||||
// This function is part of the V8 stack trace API, for more info see:
|
||||
// https://v8.dev/docs/stack-trace-api
|
||||
function prepareStackTrace(error, stack) {
|
||||
if(!hookState.enabled) return hookState.originalValue.apply(this, arguments);
|
||||
|
||||
if (sharedData.emptyCacheBetweenOperations) {
|
||||
clearCaches();
|
||||
}
|
||||
|
||||
// node gives its own errors special treatment. Mimic that behavior
|
||||
// https://github.com/nodejs/node/blob/3cbaabc4622df1b4009b9d026a1a970bdbae6e89/lib/internal/errors.js#L118-L128
|
||||
// https://github.com/nodejs/node/pull/39182
|
||||
var errorString;
|
||||
if (kIsNodeError) {
|
||||
if(kIsNodeError in error) {
|
||||
errorString = `${error.name} [${error.code}]: ${error.message}`;
|
||||
} else {
|
||||
errorString = ErrorPrototypeToString(error);
|
||||
}
|
||||
} else {
|
||||
var name = error.name || 'Error';
|
||||
var message = error.message || '';
|
||||
errorString = message ? name + ": " + message : name;
|
||||
}
|
||||
|
||||
var state = { nextPosition: null, curPosition: null };
|
||||
var processedStack = [];
|
||||
for (var i = stack.length - 1; i >= 0; i--) {
|
||||
processedStack.push('\n at ' + wrapCallSite(stack[i], state));
|
||||
state.nextPosition = state.curPosition;
|
||||
}
|
||||
state.curPosition = state.nextPosition = null;
|
||||
return errorString + processedStack.reverse().join('');
|
||||
}
|
||||
}
|
||||
|
||||
// Generate position and snippet of original source with pointer
|
||||
function getErrorSource(error) {
|
||||
var match = /\n at [^(]+ \((.*):(\d+):(\d+)\)/.exec(error.stack);
|
||||
if (match) {
|
||||
var source = match[1];
|
||||
var line = +match[2];
|
||||
var column = +match[3];
|
||||
|
||||
// Support the inline sourceContents inside the source map
|
||||
var contents = getFileContentsCache(source);
|
||||
|
||||
const sourceAsPath = tryFileURLToPath(source);
|
||||
|
||||
// Support files on disk
|
||||
if (!contents && fs && fs.existsSync(sourceAsPath)) {
|
||||
try {
|
||||
contents = fs.readFileSync(sourceAsPath, 'utf8');
|
||||
} catch (er) {
|
||||
contents = '';
|
||||
}
|
||||
}
|
||||
|
||||
// Format the line from the original source code like node does
|
||||
if (contents) {
|
||||
var code = contents.split(/(?:\r\n|\r|\n)/)[line - 1];
|
||||
if (code) {
|
||||
return source + ':' + line + '\n' + code + '\n' +
|
||||
new Array(column).join(' ') + '^';
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
function printFatalErrorUponExit (error) {
|
||||
var source = getErrorSource(error);
|
||||
|
||||
// Ensure error is printed synchronously and not truncated
|
||||
if (process.stderr._handle && process.stderr._handle.setBlocking) {
|
||||
process.stderr._handle.setBlocking(true);
|
||||
}
|
||||
|
||||
if (source) {
|
||||
console.error(source);
|
||||
}
|
||||
|
||||
// Matches node's behavior for colorized output
|
||||
console.error(
|
||||
util.inspect(error, {
|
||||
customInspect: false,
|
||||
colors: process.stderr.isTTY
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
function shimEmitUncaughtException () {
|
||||
const originalValue = process.emit;
|
||||
var hook = sharedData.processEmitHook = {
|
||||
enabled: true,
|
||||
originalValue,
|
||||
installedValue: undefined
|
||||
};
|
||||
var isTerminatingDueToFatalException = false;
|
||||
var fatalException;
|
||||
|
||||
process.emit = sharedData.processEmitHook.installedValue = function (type) {
|
||||
const hadListeners = originalValue.apply(this, arguments);
|
||||
if(hook.enabled) {
|
||||
if (type === 'uncaughtException' && !hadListeners) {
|
||||
isTerminatingDueToFatalException = true;
|
||||
fatalException = arguments[1];
|
||||
process.exit(1);
|
||||
}
|
||||
if (type === 'exit' && isTerminatingDueToFatalException) {
|
||||
printFatalErrorUponExit(fatalException);
|
||||
}
|
||||
}
|
||||
return hadListeners;
|
||||
};
|
||||
}
|
||||
|
||||
var originalRetrieveFileHandlers = sharedData.retrieveFileHandlers.slice(0);
|
||||
var originalRetrieveMapHandlers = sharedData.retrieveMapHandlers.slice(0);
|
||||
|
||||
exports.wrapCallSite = wrapCallSite;
|
||||
exports.getErrorSource = getErrorSource;
|
||||
exports.mapSourcePosition = mapSourcePosition;
|
||||
exports.retrieveSourceMap = retrieveSourceMap;
|
||||
|
||||
exports.install = function(options) {
|
||||
options = options || {};
|
||||
|
||||
if (options.environment) {
|
||||
environment = options.environment;
|
||||
if (["node", "browser", "auto"].indexOf(environment) === -1) {
|
||||
throw new Error("environment " + environment + " was unknown. Available options are {auto, browser, node}")
|
||||
}
|
||||
}
|
||||
|
||||
// Use dynamicRequire to avoid including in browser bundles
|
||||
var Module = dynamicRequire(module, 'module');
|
||||
|
||||
// Redirect subsequent imports of "source-map-support"
|
||||
// to this package
|
||||
const {redirectConflictingLibrary = true, onConflictingLibraryRedirect} = options;
|
||||
if(redirectConflictingLibrary) {
|
||||
if (!sharedData.moduleResolveFilenameHook) {
|
||||
const originalValue = Module._resolveFilename;
|
||||
const moduleResolveFilenameHook = sharedData.moduleResolveFilenameHook = {
|
||||
enabled: true,
|
||||
originalValue,
|
||||
installedValue: undefined,
|
||||
}
|
||||
Module._resolveFilename = sharedData.moduleResolveFilenameHook.installedValue = function (request, parent, isMain, options) {
|
||||
if (moduleResolveFilenameHook.enabled) {
|
||||
// Match all source-map-support entrypoints: source-map-support, source-map-support/register
|
||||
let requestRedirect;
|
||||
if (request === 'source-map-support') {
|
||||
requestRedirect = './';
|
||||
} else if (request === 'source-map-support/register') {
|
||||
requestRedirect = './register';
|
||||
}
|
||||
|
||||
if (requestRedirect !== undefined) {
|
||||
const newRequest = require.resolve(requestRedirect);
|
||||
for (const cb of sharedData.onConflictingLibraryRedirectArr) {
|
||||
cb(request, parent, isMain, options, newRequest);
|
||||
}
|
||||
request = newRequest;
|
||||
}
|
||||
}
|
||||
|
||||
return originalValue.call(this, request, parent, isMain, options);
|
||||
}
|
||||
}
|
||||
if (onConflictingLibraryRedirect) {
|
||||
sharedData.onConflictingLibraryRedirectArr.push(onConflictingLibraryRedirect);
|
||||
}
|
||||
}
|
||||
|
||||
// Allow sources to be found by methods other than reading the files
|
||||
// directly from disk.
|
||||
if (options.retrieveFile) {
|
||||
if (options.overrideRetrieveFile) {
|
||||
sharedData.retrieveFileHandlers.length = 0;
|
||||
}
|
||||
|
||||
sharedData.retrieveFileHandlers.unshift(options.retrieveFile);
|
||||
}
|
||||
|
||||
// Allow source maps to be found by methods other than reading the files
|
||||
// directly from disk.
|
||||
if (options.retrieveSourceMap) {
|
||||
if (options.overrideRetrieveSourceMap) {
|
||||
sharedData.retrieveMapHandlers.length = 0;
|
||||
}
|
||||
|
||||
sharedData.retrieveMapHandlers.unshift(options.retrieveSourceMap);
|
||||
}
|
||||
|
||||
// Support runtime transpilers that include inline source maps
|
||||
if (options.hookRequire && !isInBrowser()) {
|
||||
var $compile = Module.prototype._compile;
|
||||
|
||||
if (!$compile.__sourceMapSupport) {
|
||||
Module.prototype._compile = function(content, filename) {
|
||||
setFileContentsCache(filename, content);
|
||||
setSourceMapCache(filename, undefined);
|
||||
return $compile.call(this, content, filename);
|
||||
};
|
||||
|
||||
Module.prototype._compile.__sourceMapSupport = true;
|
||||
}
|
||||
}
|
||||
|
||||
// Configure options
|
||||
if (!sharedData.emptyCacheBetweenOperations) {
|
||||
sharedData.emptyCacheBetweenOperations = 'emptyCacheBetweenOperations' in options ?
|
||||
options.emptyCacheBetweenOperations : false;
|
||||
}
|
||||
|
||||
|
||||
// Install the error reformatter
|
||||
if (!sharedData.errorPrepareStackTraceHook) {
|
||||
const originalValue = Error.prepareStackTrace;
|
||||
sharedData.errorPrepareStackTraceHook = {
|
||||
enabled: true,
|
||||
originalValue,
|
||||
installedValue: undefined
|
||||
};
|
||||
Error.prepareStackTrace = sharedData.errorPrepareStackTraceHook.installedValue = createPrepareStackTrace(sharedData.errorPrepareStackTraceHook);
|
||||
}
|
||||
|
||||
if (!sharedData.processEmitHook) {
|
||||
var installHandler = 'handleUncaughtExceptions' in options ?
|
||||
options.handleUncaughtExceptions : true;
|
||||
|
||||
// Do not override 'uncaughtException' with our own handler in Node.js
|
||||
// Worker threads. Workers pass the error to the main thread as an event,
|
||||
// rather than printing something to stderr and exiting.
|
||||
try {
|
||||
// We need to use `dynamicRequire` because `require` on it's own will be optimized by WebPack/Browserify.
|
||||
var worker_threads = dynamicRequire(module, 'worker_threads');
|
||||
if (worker_threads.isMainThread === false) {
|
||||
installHandler = false;
|
||||
}
|
||||
} catch(e) {}
|
||||
|
||||
// Provide the option to not install the uncaught exception handler. This is
|
||||
// to support other uncaught exception handlers (in test frameworks, for
|
||||
// example). If this handler is not installed and there are no other uncaught
|
||||
// exception handlers, uncaught exceptions will be caught by node's built-in
|
||||
// exception handler and the process will still be terminated. However, the
|
||||
// generated JavaScript code will be shown above the stack trace instead of
|
||||
// the original source code.
|
||||
if (installHandler && hasGlobalProcessEventEmitter()) {
|
||||
shimEmitUncaughtException();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
exports.uninstall = function() {
|
||||
if(sharedData.processEmitHook) {
|
||||
// Disable behavior
|
||||
sharedData.processEmitHook.enabled = false;
|
||||
// If possible, remove our hook function. May not be possible if subsequent third-party hooks have wrapped around us.
|
||||
if(process.emit === sharedData.processEmitHook.installedValue) {
|
||||
process.emit = sharedData.processEmitHook.originalValue;
|
||||
}
|
||||
sharedData.processEmitHook = undefined;
|
||||
}
|
||||
if(sharedData.errorPrepareStackTraceHook) {
|
||||
// Disable behavior
|
||||
sharedData.errorPrepareStackTraceHook.enabled = false;
|
||||
// If possible or necessary, remove our hook function.
|
||||
// In vanilla environments, prepareStackTrace is `undefined`.
|
||||
// We cannot delegate to `undefined` the way we can to a function w/`.apply()`; our only option is to remove the function.
|
||||
// If we are the *first* hook installed, and another was installed on top of us, we have no choice but to remove both.
|
||||
if(Error.prepareStackTrace === sharedData.errorPrepareStackTraceHook.installedValue || typeof sharedData.errorPrepareStackTraceHook.originalValue !== 'function') {
|
||||
Error.prepareStackTrace = sharedData.errorPrepareStackTraceHook.originalValue;
|
||||
}
|
||||
sharedData.errorPrepareStackTraceHook = undefined;
|
||||
}
|
||||
if (sharedData.moduleResolveFilenameHook) {
|
||||
// Disable behavior
|
||||
sharedData.moduleResolveFilenameHook.enabled = false;
|
||||
// If possible, remove our hook function. May not be possible if subsequent third-party hooks have wrapped around us.
|
||||
var Module = dynamicRequire(module, 'module');
|
||||
if(Module._resolveFilename === sharedData.moduleResolveFilenameHook.installedValue) {
|
||||
Module._resolveFilename = sharedData.moduleResolveFilenameHook.originalValue;
|
||||
}
|
||||
sharedData.moduleResolveFilenameHook = undefined;
|
||||
}
|
||||
sharedData.onConflictingLibraryRedirectArr.length = 0;
|
||||
}
|
||||
|
||||
exports.resetRetrieveHandlers = function() {
|
||||
sharedData.retrieveFileHandlers.length = 0;
|
||||
sharedData.retrieveMapHandlers.length = 0;
|
||||
}
|
||||
19
backend/node_modules/@jridgewell/resolve-uri/LICENSE
generated
vendored
Normal file
19
backend/node_modules/@jridgewell/resolve-uri/LICENSE
generated
vendored
Normal file
@ -0,0 +1,19 @@
|
||||
Copyright 2019 Justin Ridgewell <jridgewell@google.com>
|
||||
|
||||
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.
|
||||
40
backend/node_modules/@jridgewell/resolve-uri/README.md
generated
vendored
Normal file
40
backend/node_modules/@jridgewell/resolve-uri/README.md
generated
vendored
Normal file
@ -0,0 +1,40 @@
|
||||
# @jridgewell/resolve-uri
|
||||
|
||||
> Resolve a URI relative to an optional base URI
|
||||
|
||||
Resolve any combination of absolute URIs, protocol-realtive URIs, absolute paths, or relative paths.
|
||||
|
||||
## Installation
|
||||
|
||||
```sh
|
||||
npm install @jridgewell/resolve-uri
|
||||
```
|
||||
|
||||
## Usage
|
||||
|
||||
```typescript
|
||||
function resolve(input: string, base?: string): string;
|
||||
```
|
||||
|
||||
```js
|
||||
import resolve from '@jridgewell/resolve-uri';
|
||||
|
||||
resolve('foo', 'https://example.com'); // => 'https://example.com/foo'
|
||||
```
|
||||
|
||||
| Input | Base | Resolution | Explanation |
|
||||
|-----------------------|-------------------------|--------------------------------|--------------------------------------------------------------|
|
||||
| `https://example.com` | _any_ | `https://example.com/` | Input is normalized only |
|
||||
| `//example.com` | `https://base.com/` | `https://example.com/` | Input inherits the base's protocol |
|
||||
| `//example.com` | _rest_ | `//example.com/` | Input is normalized only |
|
||||
| `/example` | `https://base.com/` | `https://base.com/example` | Input inherits the base's origin |
|
||||
| `/example` | `//base.com/` | `//base.com/example` | Input inherits the base's host and remains protocol relative |
|
||||
| `/example` | _rest_ | `/example` | Input is normalized only |
|
||||
| `example` | `https://base.com/dir/` | `https://base.com/dir/example` | Input is joined with the base |
|
||||
| `example` | `https://base.com/file` | `https://base.com/example` | Input is joined with the base without its file |
|
||||
| `example` | `//base.com/dir/` | `//base.com/dir/example` | Input is joined with the base's last directory |
|
||||
| `example` | `//base.com/file` | `//base.com/example` | Input is joined with the base without its file |
|
||||
| `example` | `/base/dir/` | `/base/dir/example` | Input is joined with the base's last directory |
|
||||
| `example` | `/base/file` | `/base/example` | Input is joined with the base without its file |
|
||||
| `example` | `base/dir/` | `base/dir/example` | Input is joined with the base's last directory |
|
||||
| `example` | `base/file` | `base/example` | Input is joined with the base without its file |
|
||||
232
backend/node_modules/@jridgewell/resolve-uri/dist/resolve-uri.mjs
generated
vendored
Normal file
232
backend/node_modules/@jridgewell/resolve-uri/dist/resolve-uri.mjs
generated
vendored
Normal file
@ -0,0 +1,232 @@
|
||||
// Matches the scheme of a URL, eg "http://"
|
||||
const schemeRegex = /^[\w+.-]+:\/\//;
|
||||
/**
|
||||
* Matches the parts of a URL:
|
||||
* 1. Scheme, including ":", guaranteed.
|
||||
* 2. User/password, including "@", optional.
|
||||
* 3. Host, guaranteed.
|
||||
* 4. Port, including ":", optional.
|
||||
* 5. Path, including "/", optional.
|
||||
* 6. Query, including "?", optional.
|
||||
* 7. Hash, including "#", optional.
|
||||
*/
|
||||
const urlRegex = /^([\w+.-]+:)\/\/([^@/#?]*@)?([^:/#?]*)(:\d+)?(\/[^#?]*)?(\?[^#]*)?(#.*)?/;
|
||||
/**
|
||||
* File URLs are weird. They dont' need the regular `//` in the scheme, they may or may not start
|
||||
* with a leading `/`, they can have a domain (but only if they don't start with a Windows drive).
|
||||
*
|
||||
* 1. Host, optional.
|
||||
* 2. Path, which may include "/", guaranteed.
|
||||
* 3. Query, including "?", optional.
|
||||
* 4. Hash, including "#", optional.
|
||||
*/
|
||||
const fileRegex = /^file:(?:\/\/((?![a-z]:)[^/#?]*)?)?(\/?[^#?]*)(\?[^#]*)?(#.*)?/i;
|
||||
function isAbsoluteUrl(input) {
|
||||
return schemeRegex.test(input);
|
||||
}
|
||||
function isSchemeRelativeUrl(input) {
|
||||
return input.startsWith('//');
|
||||
}
|
||||
function isAbsolutePath(input) {
|
||||
return input.startsWith('/');
|
||||
}
|
||||
function isFileUrl(input) {
|
||||
return input.startsWith('file:');
|
||||
}
|
||||
function isRelative(input) {
|
||||
return /^[.?#]/.test(input);
|
||||
}
|
||||
function parseAbsoluteUrl(input) {
|
||||
const match = urlRegex.exec(input);
|
||||
return makeUrl(match[1], match[2] || '', match[3], match[4] || '', match[5] || '/', match[6] || '', match[7] || '');
|
||||
}
|
||||
function parseFileUrl(input) {
|
||||
const match = fileRegex.exec(input);
|
||||
const path = match[2];
|
||||
return makeUrl('file:', '', match[1] || '', '', isAbsolutePath(path) ? path : '/' + path, match[3] || '', match[4] || '');
|
||||
}
|
||||
function makeUrl(scheme, user, host, port, path, query, hash) {
|
||||
return {
|
||||
scheme,
|
||||
user,
|
||||
host,
|
||||
port,
|
||||
path,
|
||||
query,
|
||||
hash,
|
||||
type: 7 /* Absolute */,
|
||||
};
|
||||
}
|
||||
function parseUrl(input) {
|
||||
if (isSchemeRelativeUrl(input)) {
|
||||
const url = parseAbsoluteUrl('http:' + input);
|
||||
url.scheme = '';
|
||||
url.type = 6 /* SchemeRelative */;
|
||||
return url;
|
||||
}
|
||||
if (isAbsolutePath(input)) {
|
||||
const url = parseAbsoluteUrl('http://foo.com' + input);
|
||||
url.scheme = '';
|
||||
url.host = '';
|
||||
url.type = 5 /* AbsolutePath */;
|
||||
return url;
|
||||
}
|
||||
if (isFileUrl(input))
|
||||
return parseFileUrl(input);
|
||||
if (isAbsoluteUrl(input))
|
||||
return parseAbsoluteUrl(input);
|
||||
const url = parseAbsoluteUrl('http://foo.com/' + input);
|
||||
url.scheme = '';
|
||||
url.host = '';
|
||||
url.type = input
|
||||
? input.startsWith('?')
|
||||
? 3 /* Query */
|
||||
: input.startsWith('#')
|
||||
? 2 /* Hash */
|
||||
: 4 /* RelativePath */
|
||||
: 1 /* Empty */;
|
||||
return url;
|
||||
}
|
||||
function stripPathFilename(path) {
|
||||
// If a path ends with a parent directory "..", then it's a relative path with excess parent
|
||||
// paths. It's not a file, so we can't strip it.
|
||||
if (path.endsWith('/..'))
|
||||
return path;
|
||||
const index = path.lastIndexOf('/');
|
||||
return path.slice(0, index + 1);
|
||||
}
|
||||
function mergePaths(url, base) {
|
||||
normalizePath(base, base.type);
|
||||
// If the path is just a "/", then it was an empty path to begin with (remember, we're a relative
|
||||
// path).
|
||||
if (url.path === '/') {
|
||||
url.path = base.path;
|
||||
}
|
||||
else {
|
||||
// Resolution happens relative to the base path's directory, not the file.
|
||||
url.path = stripPathFilename(base.path) + url.path;
|
||||
}
|
||||
}
|
||||
/**
|
||||
* The path can have empty directories "//", unneeded parents "foo/..", or current directory
|
||||
* "foo/.". We need to normalize to a standard representation.
|
||||
*/
|
||||
function normalizePath(url, type) {
|
||||
const rel = type <= 4 /* RelativePath */;
|
||||
const pieces = url.path.split('/');
|
||||
// We need to preserve the first piece always, so that we output a leading slash. The item at
|
||||
// pieces[0] is an empty string.
|
||||
let pointer = 1;
|
||||
// Positive is the number of real directories we've output, used for popping a parent directory.
|
||||
// Eg, "foo/bar/.." will have a positive 2, and we can decrement to be left with just "foo".
|
||||
let positive = 0;
|
||||
// We need to keep a trailing slash if we encounter an empty directory (eg, splitting "foo/" will
|
||||
// generate `["foo", ""]` pieces). And, if we pop a parent directory. But once we encounter a
|
||||
// real directory, we won't need to append, unless the other conditions happen again.
|
||||
let addTrailingSlash = false;
|
||||
for (let i = 1; i < pieces.length; i++) {
|
||||
const piece = pieces[i];
|
||||
// An empty directory, could be a trailing slash, or just a double "//" in the path.
|
||||
if (!piece) {
|
||||
addTrailingSlash = true;
|
||||
continue;
|
||||
}
|
||||
// If we encounter a real directory, then we don't need to append anymore.
|
||||
addTrailingSlash = false;
|
||||
// A current directory, which we can always drop.
|
||||
if (piece === '.')
|
||||
continue;
|
||||
// A parent directory, we need to see if there are any real directories we can pop. Else, we
|
||||
// have an excess of parents, and we'll need to keep the "..".
|
||||
if (piece === '..') {
|
||||
if (positive) {
|
||||
addTrailingSlash = true;
|
||||
positive--;
|
||||
pointer--;
|
||||
}
|
||||
else if (rel) {
|
||||
// If we're in a relativePath, then we need to keep the excess parents. Else, in an absolute
|
||||
// URL, protocol relative URL, or an absolute path, we don't need to keep excess.
|
||||
pieces[pointer++] = piece;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
// We've encountered a real directory. Move it to the next insertion pointer, which accounts for
|
||||
// any popped or dropped directories.
|
||||
pieces[pointer++] = piece;
|
||||
positive++;
|
||||
}
|
||||
let path = '';
|
||||
for (let i = 1; i < pointer; i++) {
|
||||
path += '/' + pieces[i];
|
||||
}
|
||||
if (!path || (addTrailingSlash && !path.endsWith('/..'))) {
|
||||
path += '/';
|
||||
}
|
||||
url.path = path;
|
||||
}
|
||||
/**
|
||||
* Attempts to resolve `input` URL/path relative to `base`.
|
||||
*/
|
||||
function resolve(input, base) {
|
||||
if (!input && !base)
|
||||
return '';
|
||||
const url = parseUrl(input);
|
||||
let inputType = url.type;
|
||||
if (base && inputType !== 7 /* Absolute */) {
|
||||
const baseUrl = parseUrl(base);
|
||||
const baseType = baseUrl.type;
|
||||
switch (inputType) {
|
||||
case 1 /* Empty */:
|
||||
url.hash = baseUrl.hash;
|
||||
// fall through
|
||||
case 2 /* Hash */:
|
||||
url.query = baseUrl.query;
|
||||
// fall through
|
||||
case 3 /* Query */:
|
||||
case 4 /* RelativePath */:
|
||||
mergePaths(url, baseUrl);
|
||||
// fall through
|
||||
case 5 /* AbsolutePath */:
|
||||
// The host, user, and port are joined, you can't copy one without the others.
|
||||
url.user = baseUrl.user;
|
||||
url.host = baseUrl.host;
|
||||
url.port = baseUrl.port;
|
||||
// fall through
|
||||
case 6 /* SchemeRelative */:
|
||||
// The input doesn't have a schema at least, so we need to copy at least that over.
|
||||
url.scheme = baseUrl.scheme;
|
||||
}
|
||||
if (baseType > inputType)
|
||||
inputType = baseType;
|
||||
}
|
||||
normalizePath(url, inputType);
|
||||
const queryHash = url.query + url.hash;
|
||||
switch (inputType) {
|
||||
// This is impossible, because of the empty checks at the start of the function.
|
||||
// case UrlType.Empty:
|
||||
case 2 /* Hash */:
|
||||
case 3 /* Query */:
|
||||
return queryHash;
|
||||
case 4 /* RelativePath */: {
|
||||
// The first char is always a "/", and we need it to be relative.
|
||||
const path = url.path.slice(1);
|
||||
if (!path)
|
||||
return queryHash || '.';
|
||||
if (isRelative(base || input) && !isRelative(path)) {
|
||||
// If base started with a leading ".", or there is no base and input started with a ".",
|
||||
// then we need to ensure that the relative path starts with a ".". We don't know if
|
||||
// relative starts with a "..", though, so check before prepending.
|
||||
return './' + path + queryHash;
|
||||
}
|
||||
return path + queryHash;
|
||||
}
|
||||
case 5 /* AbsolutePath */:
|
||||
return url.path + queryHash;
|
||||
default:
|
||||
return url.scheme + '//' + url.user + url.host + url.port + url.path + queryHash;
|
||||
}
|
||||
}
|
||||
|
||||
export { resolve as default };
|
||||
//# sourceMappingURL=resolve-uri.mjs.map
|
||||
1
backend/node_modules/@jridgewell/resolve-uri/dist/resolve-uri.mjs.map
generated
vendored
Normal file
1
backend/node_modules/@jridgewell/resolve-uri/dist/resolve-uri.mjs.map
generated
vendored
Normal file
File diff suppressed because one or more lines are too long
240
backend/node_modules/@jridgewell/resolve-uri/dist/resolve-uri.umd.js
generated
vendored
Normal file
240
backend/node_modules/@jridgewell/resolve-uri/dist/resolve-uri.umd.js
generated
vendored
Normal file
@ -0,0 +1,240 @@
|
||||
(function (global, factory) {
|
||||
typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :
|
||||
typeof define === 'function' && define.amd ? define(factory) :
|
||||
(global = typeof globalThis !== 'undefined' ? globalThis : global || self, global.resolveURI = factory());
|
||||
})(this, (function () { 'use strict';
|
||||
|
||||
// Matches the scheme of a URL, eg "http://"
|
||||
const schemeRegex = /^[\w+.-]+:\/\//;
|
||||
/**
|
||||
* Matches the parts of a URL:
|
||||
* 1. Scheme, including ":", guaranteed.
|
||||
* 2. User/password, including "@", optional.
|
||||
* 3. Host, guaranteed.
|
||||
* 4. Port, including ":", optional.
|
||||
* 5. Path, including "/", optional.
|
||||
* 6. Query, including "?", optional.
|
||||
* 7. Hash, including "#", optional.
|
||||
*/
|
||||
const urlRegex = /^([\w+.-]+:)\/\/([^@/#?]*@)?([^:/#?]*)(:\d+)?(\/[^#?]*)?(\?[^#]*)?(#.*)?/;
|
||||
/**
|
||||
* File URLs are weird. They dont' need the regular `//` in the scheme, they may or may not start
|
||||
* with a leading `/`, they can have a domain (but only if they don't start with a Windows drive).
|
||||
*
|
||||
* 1. Host, optional.
|
||||
* 2. Path, which may include "/", guaranteed.
|
||||
* 3. Query, including "?", optional.
|
||||
* 4. Hash, including "#", optional.
|
||||
*/
|
||||
const fileRegex = /^file:(?:\/\/((?![a-z]:)[^/#?]*)?)?(\/?[^#?]*)(\?[^#]*)?(#.*)?/i;
|
||||
function isAbsoluteUrl(input) {
|
||||
return schemeRegex.test(input);
|
||||
}
|
||||
function isSchemeRelativeUrl(input) {
|
||||
return input.startsWith('//');
|
||||
}
|
||||
function isAbsolutePath(input) {
|
||||
return input.startsWith('/');
|
||||
}
|
||||
function isFileUrl(input) {
|
||||
return input.startsWith('file:');
|
||||
}
|
||||
function isRelative(input) {
|
||||
return /^[.?#]/.test(input);
|
||||
}
|
||||
function parseAbsoluteUrl(input) {
|
||||
const match = urlRegex.exec(input);
|
||||
return makeUrl(match[1], match[2] || '', match[3], match[4] || '', match[5] || '/', match[6] || '', match[7] || '');
|
||||
}
|
||||
function parseFileUrl(input) {
|
||||
const match = fileRegex.exec(input);
|
||||
const path = match[2];
|
||||
return makeUrl('file:', '', match[1] || '', '', isAbsolutePath(path) ? path : '/' + path, match[3] || '', match[4] || '');
|
||||
}
|
||||
function makeUrl(scheme, user, host, port, path, query, hash) {
|
||||
return {
|
||||
scheme,
|
||||
user,
|
||||
host,
|
||||
port,
|
||||
path,
|
||||
query,
|
||||
hash,
|
||||
type: 7 /* Absolute */,
|
||||
};
|
||||
}
|
||||
function parseUrl(input) {
|
||||
if (isSchemeRelativeUrl(input)) {
|
||||
const url = parseAbsoluteUrl('http:' + input);
|
||||
url.scheme = '';
|
||||
url.type = 6 /* SchemeRelative */;
|
||||
return url;
|
||||
}
|
||||
if (isAbsolutePath(input)) {
|
||||
const url = parseAbsoluteUrl('http://foo.com' + input);
|
||||
url.scheme = '';
|
||||
url.host = '';
|
||||
url.type = 5 /* AbsolutePath */;
|
||||
return url;
|
||||
}
|
||||
if (isFileUrl(input))
|
||||
return parseFileUrl(input);
|
||||
if (isAbsoluteUrl(input))
|
||||
return parseAbsoluteUrl(input);
|
||||
const url = parseAbsoluteUrl('http://foo.com/' + input);
|
||||
url.scheme = '';
|
||||
url.host = '';
|
||||
url.type = input
|
||||
? input.startsWith('?')
|
||||
? 3 /* Query */
|
||||
: input.startsWith('#')
|
||||
? 2 /* Hash */
|
||||
: 4 /* RelativePath */
|
||||
: 1 /* Empty */;
|
||||
return url;
|
||||
}
|
||||
function stripPathFilename(path) {
|
||||
// If a path ends with a parent directory "..", then it's a relative path with excess parent
|
||||
// paths. It's not a file, so we can't strip it.
|
||||
if (path.endsWith('/..'))
|
||||
return path;
|
||||
const index = path.lastIndexOf('/');
|
||||
return path.slice(0, index + 1);
|
||||
}
|
||||
function mergePaths(url, base) {
|
||||
normalizePath(base, base.type);
|
||||
// If the path is just a "/", then it was an empty path to begin with (remember, we're a relative
|
||||
// path).
|
||||
if (url.path === '/') {
|
||||
url.path = base.path;
|
||||
}
|
||||
else {
|
||||
// Resolution happens relative to the base path's directory, not the file.
|
||||
url.path = stripPathFilename(base.path) + url.path;
|
||||
}
|
||||
}
|
||||
/**
|
||||
* The path can have empty directories "//", unneeded parents "foo/..", or current directory
|
||||
* "foo/.". We need to normalize to a standard representation.
|
||||
*/
|
||||
function normalizePath(url, type) {
|
||||
const rel = type <= 4 /* RelativePath */;
|
||||
const pieces = url.path.split('/');
|
||||
// We need to preserve the first piece always, so that we output a leading slash. The item at
|
||||
// pieces[0] is an empty string.
|
||||
let pointer = 1;
|
||||
// Positive is the number of real directories we've output, used for popping a parent directory.
|
||||
// Eg, "foo/bar/.." will have a positive 2, and we can decrement to be left with just "foo".
|
||||
let positive = 0;
|
||||
// We need to keep a trailing slash if we encounter an empty directory (eg, splitting "foo/" will
|
||||
// generate `["foo", ""]` pieces). And, if we pop a parent directory. But once we encounter a
|
||||
// real directory, we won't need to append, unless the other conditions happen again.
|
||||
let addTrailingSlash = false;
|
||||
for (let i = 1; i < pieces.length; i++) {
|
||||
const piece = pieces[i];
|
||||
// An empty directory, could be a trailing slash, or just a double "//" in the path.
|
||||
if (!piece) {
|
||||
addTrailingSlash = true;
|
||||
continue;
|
||||
}
|
||||
// If we encounter a real directory, then we don't need to append anymore.
|
||||
addTrailingSlash = false;
|
||||
// A current directory, which we can always drop.
|
||||
if (piece === '.')
|
||||
continue;
|
||||
// A parent directory, we need to see if there are any real directories we can pop. Else, we
|
||||
// have an excess of parents, and we'll need to keep the "..".
|
||||
if (piece === '..') {
|
||||
if (positive) {
|
||||
addTrailingSlash = true;
|
||||
positive--;
|
||||
pointer--;
|
||||
}
|
||||
else if (rel) {
|
||||
// If we're in a relativePath, then we need to keep the excess parents. Else, in an absolute
|
||||
// URL, protocol relative URL, or an absolute path, we don't need to keep excess.
|
||||
pieces[pointer++] = piece;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
// We've encountered a real directory. Move it to the next insertion pointer, which accounts for
|
||||
// any popped or dropped directories.
|
||||
pieces[pointer++] = piece;
|
||||
positive++;
|
||||
}
|
||||
let path = '';
|
||||
for (let i = 1; i < pointer; i++) {
|
||||
path += '/' + pieces[i];
|
||||
}
|
||||
if (!path || (addTrailingSlash && !path.endsWith('/..'))) {
|
||||
path += '/';
|
||||
}
|
||||
url.path = path;
|
||||
}
|
||||
/**
|
||||
* Attempts to resolve `input` URL/path relative to `base`.
|
||||
*/
|
||||
function resolve(input, base) {
|
||||
if (!input && !base)
|
||||
return '';
|
||||
const url = parseUrl(input);
|
||||
let inputType = url.type;
|
||||
if (base && inputType !== 7 /* Absolute */) {
|
||||
const baseUrl = parseUrl(base);
|
||||
const baseType = baseUrl.type;
|
||||
switch (inputType) {
|
||||
case 1 /* Empty */:
|
||||
url.hash = baseUrl.hash;
|
||||
// fall through
|
||||
case 2 /* Hash */:
|
||||
url.query = baseUrl.query;
|
||||
// fall through
|
||||
case 3 /* Query */:
|
||||
case 4 /* RelativePath */:
|
||||
mergePaths(url, baseUrl);
|
||||
// fall through
|
||||
case 5 /* AbsolutePath */:
|
||||
// The host, user, and port are joined, you can't copy one without the others.
|
||||
url.user = baseUrl.user;
|
||||
url.host = baseUrl.host;
|
||||
url.port = baseUrl.port;
|
||||
// fall through
|
||||
case 6 /* SchemeRelative */:
|
||||
// The input doesn't have a schema at least, so we need to copy at least that over.
|
||||
url.scheme = baseUrl.scheme;
|
||||
}
|
||||
if (baseType > inputType)
|
||||
inputType = baseType;
|
||||
}
|
||||
normalizePath(url, inputType);
|
||||
const queryHash = url.query + url.hash;
|
||||
switch (inputType) {
|
||||
// This is impossible, because of the empty checks at the start of the function.
|
||||
// case UrlType.Empty:
|
||||
case 2 /* Hash */:
|
||||
case 3 /* Query */:
|
||||
return queryHash;
|
||||
case 4 /* RelativePath */: {
|
||||
// The first char is always a "/", and we need it to be relative.
|
||||
const path = url.path.slice(1);
|
||||
if (!path)
|
||||
return queryHash || '.';
|
||||
if (isRelative(base || input) && !isRelative(path)) {
|
||||
// If base started with a leading ".", or there is no base and input started with a ".",
|
||||
// then we need to ensure that the relative path starts with a ".". We don't know if
|
||||
// relative starts with a "..", though, so check before prepending.
|
||||
return './' + path + queryHash;
|
||||
}
|
||||
return path + queryHash;
|
||||
}
|
||||
case 5 /* AbsolutePath */:
|
||||
return url.path + queryHash;
|
||||
default:
|
||||
return url.scheme + '//' + url.user + url.host + url.port + url.path + queryHash;
|
||||
}
|
||||
}
|
||||
|
||||
return resolve;
|
||||
|
||||
}));
|
||||
//# sourceMappingURL=resolve-uri.umd.js.map
|
||||
1
backend/node_modules/@jridgewell/resolve-uri/dist/resolve-uri.umd.js.map
generated
vendored
Normal file
1
backend/node_modules/@jridgewell/resolve-uri/dist/resolve-uri.umd.js.map
generated
vendored
Normal file
File diff suppressed because one or more lines are too long
4
backend/node_modules/@jridgewell/resolve-uri/dist/types/resolve-uri.d.ts
generated
vendored
Normal file
4
backend/node_modules/@jridgewell/resolve-uri/dist/types/resolve-uri.d.ts
generated
vendored
Normal file
@ -0,0 +1,4 @@
|
||||
/**
|
||||
* Attempts to resolve `input` URL/path relative to `base`.
|
||||
*/
|
||||
export default function resolve(input: string, base: string | undefined): string;
|
||||
69
backend/node_modules/@jridgewell/resolve-uri/package.json
generated
vendored
Normal file
69
backend/node_modules/@jridgewell/resolve-uri/package.json
generated
vendored
Normal file
@ -0,0 +1,69 @@
|
||||
{
|
||||
"name": "@jridgewell/resolve-uri",
|
||||
"version": "3.1.2",
|
||||
"description": "Resolve a URI relative to an optional base URI",
|
||||
"keywords": [
|
||||
"resolve",
|
||||
"uri",
|
||||
"url",
|
||||
"path"
|
||||
],
|
||||
"author": "Justin Ridgewell <justin@ridgewell.name>",
|
||||
"license": "MIT",
|
||||
"repository": "https://github.com/jridgewell/resolve-uri",
|
||||
"main": "dist/resolve-uri.umd.js",
|
||||
"module": "dist/resolve-uri.mjs",
|
||||
"types": "dist/types/resolve-uri.d.ts",
|
||||
"exports": {
|
||||
".": [
|
||||
{
|
||||
"types": "./dist/types/resolve-uri.d.ts",
|
||||
"browser": "./dist/resolve-uri.umd.js",
|
||||
"require": "./dist/resolve-uri.umd.js",
|
||||
"import": "./dist/resolve-uri.mjs"
|
||||
},
|
||||
"./dist/resolve-uri.umd.js"
|
||||
],
|
||||
"./package.json": "./package.json"
|
||||
},
|
||||
"files": [
|
||||
"dist"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=6.0.0"
|
||||
},
|
||||
"scripts": {
|
||||
"prebuild": "rm -rf dist",
|
||||
"build": "run-s -n build:*",
|
||||
"build:rollup": "rollup -c rollup.config.js",
|
||||
"build:ts": "tsc --project tsconfig.build.json",
|
||||
"lint": "run-s -n lint:*",
|
||||
"lint:prettier": "npm run test:lint:prettier -- --write",
|
||||
"lint:ts": "npm run test:lint:ts -- --fix",
|
||||
"pretest": "run-s build:rollup",
|
||||
"test": "run-s -n test:lint test:only",
|
||||
"test:debug": "mocha --inspect-brk",
|
||||
"test:lint": "run-s -n test:lint:*",
|
||||
"test:lint:prettier": "prettier --check '{src,test}/**/*.ts'",
|
||||
"test:lint:ts": "eslint '{src,test}/**/*.ts'",
|
||||
"test:only": "mocha",
|
||||
"test:coverage": "c8 mocha",
|
||||
"test:watch": "mocha --watch",
|
||||
"prepublishOnly": "npm run preversion",
|
||||
"preversion": "run-s test build"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@jridgewell/resolve-uri-latest": "npm:@jridgewell/resolve-uri@*",
|
||||
"@rollup/plugin-typescript": "8.3.0",
|
||||
"@typescript-eslint/eslint-plugin": "5.10.0",
|
||||
"@typescript-eslint/parser": "5.10.0",
|
||||
"c8": "7.11.0",
|
||||
"eslint": "8.7.0",
|
||||
"eslint-config-prettier": "8.3.0",
|
||||
"mocha": "9.2.0",
|
||||
"npm-run-all": "4.1.5",
|
||||
"prettier": "2.5.1",
|
||||
"rollup": "2.66.0",
|
||||
"typescript": "4.5.5"
|
||||
}
|
||||
}
|
||||
19
backend/node_modules/@jridgewell/sourcemap-codec/LICENSE
generated
vendored
Normal file
19
backend/node_modules/@jridgewell/sourcemap-codec/LICENSE
generated
vendored
Normal file
@ -0,0 +1,19 @@
|
||||
Copyright 2024 Justin Ridgewell <justin@ridgewell.name>
|
||||
|
||||
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.
|
||||
264
backend/node_modules/@jridgewell/sourcemap-codec/README.md
generated
vendored
Normal file
264
backend/node_modules/@jridgewell/sourcemap-codec/README.md
generated
vendored
Normal file
@ -0,0 +1,264 @@
|
||||
# @jridgewell/sourcemap-codec
|
||||
|
||||
Encode/decode the `mappings` property of a [sourcemap](https://docs.google.com/document/d/1U1RGAehQwRypUTovF1KRlpiOFze0b-_2gc6fAH0KY0k/edit).
|
||||
|
||||
|
||||
## Why?
|
||||
|
||||
Sourcemaps are difficult to generate and manipulate, because the `mappings` property – the part that actually links the generated code back to the original source – is encoded using an obscure method called [Variable-length quantity](https://en.wikipedia.org/wiki/Variable-length_quantity). On top of that, each segment in the mapping contains offsets rather than absolute indices, which means that you can't look at a segment in isolation – you have to understand the whole sourcemap.
|
||||
|
||||
This package makes the process slightly easier.
|
||||
|
||||
|
||||
## Installation
|
||||
|
||||
```bash
|
||||
npm install @jridgewell/sourcemap-codec
|
||||
```
|
||||
|
||||
|
||||
## Usage
|
||||
|
||||
```js
|
||||
import { encode, decode } from '@jridgewell/sourcemap-codec';
|
||||
|
||||
var decoded = decode( ';EAEEA,EAAE,EAAC,CAAE;ECQY,UACC' );
|
||||
|
||||
assert.deepEqual( decoded, [
|
||||
// the first line (of the generated code) has no mappings,
|
||||
// as shown by the starting semi-colon (which separates lines)
|
||||
[],
|
||||
|
||||
// the second line contains four (comma-separated) segments
|
||||
[
|
||||
// segments are encoded as you'd expect:
|
||||
// [ generatedCodeColumn, sourceIndex, sourceCodeLine, sourceCodeColumn, nameIndex ]
|
||||
|
||||
// i.e. the first segment begins at column 2, and maps back to the second column
|
||||
// of the second line (both zero-based) of the 0th source, and uses the 0th
|
||||
// name in the `map.names` array
|
||||
[ 2, 0, 2, 2, 0 ],
|
||||
|
||||
// the remaining segments are 4-length rather than 5-length,
|
||||
// because they don't map a name
|
||||
[ 4, 0, 2, 4 ],
|
||||
[ 6, 0, 2, 5 ],
|
||||
[ 7, 0, 2, 7 ]
|
||||
],
|
||||
|
||||
// the final line contains two segments
|
||||
[
|
||||
[ 2, 1, 10, 19 ],
|
||||
[ 12, 1, 11, 20 ]
|
||||
]
|
||||
]);
|
||||
|
||||
var encoded = encode( decoded );
|
||||
assert.equal( encoded, ';EAEEA,EAAE,EAAC,CAAE;ECQY,UACC' );
|
||||
```
|
||||
|
||||
## Benchmarks
|
||||
|
||||
```
|
||||
node v20.10.0
|
||||
|
||||
amp.js.map - 45120 segments
|
||||
|
||||
Decode Memory Usage:
|
||||
local code 5815135 bytes
|
||||
@jridgewell/sourcemap-codec 1.4.15 5868160 bytes
|
||||
sourcemap-codec 5492584 bytes
|
||||
source-map-0.6.1 13569984 bytes
|
||||
source-map-0.8.0 6390584 bytes
|
||||
chrome dev tools 8011136 bytes
|
||||
Smallest memory usage is sourcemap-codec
|
||||
|
||||
Decode speed:
|
||||
decode: local code x 492 ops/sec ±1.22% (90 runs sampled)
|
||||
decode: @jridgewell/sourcemap-codec 1.4.15 x 499 ops/sec ±1.16% (89 runs sampled)
|
||||
decode: sourcemap-codec x 376 ops/sec ±1.66% (89 runs sampled)
|
||||
decode: source-map-0.6.1 x 34.99 ops/sec ±0.94% (48 runs sampled)
|
||||
decode: source-map-0.8.0 x 351 ops/sec ±0.07% (95 runs sampled)
|
||||
chrome dev tools x 165 ops/sec ±0.91% (86 runs sampled)
|
||||
Fastest is decode: @jridgewell/sourcemap-codec 1.4.15
|
||||
|
||||
Encode Memory Usage:
|
||||
local code 444248 bytes
|
||||
@jridgewell/sourcemap-codec 1.4.15 623024 bytes
|
||||
sourcemap-codec 8696280 bytes
|
||||
source-map-0.6.1 8745176 bytes
|
||||
source-map-0.8.0 8736624 bytes
|
||||
Smallest memory usage is local code
|
||||
|
||||
Encode speed:
|
||||
encode: local code x 796 ops/sec ±0.11% (97 runs sampled)
|
||||
encode: @jridgewell/sourcemap-codec 1.4.15 x 795 ops/sec ±0.25% (98 runs sampled)
|
||||
encode: sourcemap-codec x 231 ops/sec ±0.83% (86 runs sampled)
|
||||
encode: source-map-0.6.1 x 166 ops/sec ±0.57% (86 runs sampled)
|
||||
encode: source-map-0.8.0 x 203 ops/sec ±0.45% (88 runs sampled)
|
||||
Fastest is encode: local code,encode: @jridgewell/sourcemap-codec 1.4.15
|
||||
|
||||
|
||||
***
|
||||
|
||||
|
||||
babel.min.js.map - 347793 segments
|
||||
|
||||
Decode Memory Usage:
|
||||
local code 35424960 bytes
|
||||
@jridgewell/sourcemap-codec 1.4.15 35424696 bytes
|
||||
sourcemap-codec 36033464 bytes
|
||||
source-map-0.6.1 62253704 bytes
|
||||
source-map-0.8.0 43843920 bytes
|
||||
chrome dev tools 45111400 bytes
|
||||
Smallest memory usage is @jridgewell/sourcemap-codec 1.4.15
|
||||
|
||||
Decode speed:
|
||||
decode: local code x 38.18 ops/sec ±5.44% (52 runs sampled)
|
||||
decode: @jridgewell/sourcemap-codec 1.4.15 x 38.36 ops/sec ±5.02% (52 runs sampled)
|
||||
decode: sourcemap-codec x 34.05 ops/sec ±4.45% (47 runs sampled)
|
||||
decode: source-map-0.6.1 x 4.31 ops/sec ±2.76% (15 runs sampled)
|
||||
decode: source-map-0.8.0 x 55.60 ops/sec ±0.13% (73 runs sampled)
|
||||
chrome dev tools x 16.94 ops/sec ±3.78% (46 runs sampled)
|
||||
Fastest is decode: source-map-0.8.0
|
||||
|
||||
Encode Memory Usage:
|
||||
local code 2606016 bytes
|
||||
@jridgewell/sourcemap-codec 1.4.15 2626440 bytes
|
||||
sourcemap-codec 21152576 bytes
|
||||
source-map-0.6.1 25023928 bytes
|
||||
source-map-0.8.0 25256448 bytes
|
||||
Smallest memory usage is local code
|
||||
|
||||
Encode speed:
|
||||
encode: local code x 127 ops/sec ±0.18% (83 runs sampled)
|
||||
encode: @jridgewell/sourcemap-codec 1.4.15 x 128 ops/sec ±0.26% (83 runs sampled)
|
||||
encode: sourcemap-codec x 29.31 ops/sec ±2.55% (53 runs sampled)
|
||||
encode: source-map-0.6.1 x 18.85 ops/sec ±3.19% (36 runs sampled)
|
||||
encode: source-map-0.8.0 x 19.34 ops/sec ±1.97% (36 runs sampled)
|
||||
Fastest is encode: @jridgewell/sourcemap-codec 1.4.15
|
||||
|
||||
|
||||
***
|
||||
|
||||
|
||||
preact.js.map - 1992 segments
|
||||
|
||||
Decode Memory Usage:
|
||||
local code 261696 bytes
|
||||
@jridgewell/sourcemap-codec 1.4.15 244296 bytes
|
||||
sourcemap-codec 302816 bytes
|
||||
source-map-0.6.1 939176 bytes
|
||||
source-map-0.8.0 336 bytes
|
||||
chrome dev tools 587368 bytes
|
||||
Smallest memory usage is source-map-0.8.0
|
||||
|
||||
Decode speed:
|
||||
decode: local code x 17,782 ops/sec ±0.32% (97 runs sampled)
|
||||
decode: @jridgewell/sourcemap-codec 1.4.15 x 17,863 ops/sec ±0.40% (100 runs sampled)
|
||||
decode: sourcemap-codec x 12,453 ops/sec ±0.27% (101 runs sampled)
|
||||
decode: source-map-0.6.1 x 1,288 ops/sec ±1.05% (96 runs sampled)
|
||||
decode: source-map-0.8.0 x 9,289 ops/sec ±0.27% (101 runs sampled)
|
||||
chrome dev tools x 4,769 ops/sec ±0.18% (100 runs sampled)
|
||||
Fastest is decode: @jridgewell/sourcemap-codec 1.4.15
|
||||
|
||||
Encode Memory Usage:
|
||||
local code 262944 bytes
|
||||
@jridgewell/sourcemap-codec 1.4.15 25544 bytes
|
||||
sourcemap-codec 323048 bytes
|
||||
source-map-0.6.1 507808 bytes
|
||||
source-map-0.8.0 507480 bytes
|
||||
Smallest memory usage is @jridgewell/sourcemap-codec 1.4.15
|
||||
|
||||
Encode speed:
|
||||
encode: local code x 24,207 ops/sec ±0.79% (95 runs sampled)
|
||||
encode: @jridgewell/sourcemap-codec 1.4.15 x 24,288 ops/sec ±0.48% (96 runs sampled)
|
||||
encode: sourcemap-codec x 6,761 ops/sec ±0.21% (100 runs sampled)
|
||||
encode: source-map-0.6.1 x 5,374 ops/sec ±0.17% (99 runs sampled)
|
||||
encode: source-map-0.8.0 x 5,633 ops/sec ±0.32% (99 runs sampled)
|
||||
Fastest is encode: @jridgewell/sourcemap-codec 1.4.15,encode: local code
|
||||
|
||||
|
||||
***
|
||||
|
||||
|
||||
react.js.map - 5726 segments
|
||||
|
||||
Decode Memory Usage:
|
||||
local code 678816 bytes
|
||||
@jridgewell/sourcemap-codec 1.4.15 678816 bytes
|
||||
sourcemap-codec 816400 bytes
|
||||
source-map-0.6.1 2288864 bytes
|
||||
source-map-0.8.0 721360 bytes
|
||||
chrome dev tools 1012512 bytes
|
||||
Smallest memory usage is local code
|
||||
|
||||
Decode speed:
|
||||
decode: local code x 6,178 ops/sec ±0.19% (98 runs sampled)
|
||||
decode: @jridgewell/sourcemap-codec 1.4.15 x 6,261 ops/sec ±0.22% (100 runs sampled)
|
||||
decode: sourcemap-codec x 4,472 ops/sec ±0.90% (99 runs sampled)
|
||||
decode: source-map-0.6.1 x 449 ops/sec ±0.31% (95 runs sampled)
|
||||
decode: source-map-0.8.0 x 3,219 ops/sec ±0.13% (100 runs sampled)
|
||||
chrome dev tools x 1,743 ops/sec ±0.20% (99 runs sampled)
|
||||
Fastest is decode: @jridgewell/sourcemap-codec 1.4.15
|
||||
|
||||
Encode Memory Usage:
|
||||
local code 140960 bytes
|
||||
@jridgewell/sourcemap-codec 1.4.15 159808 bytes
|
||||
sourcemap-codec 969304 bytes
|
||||
source-map-0.6.1 930520 bytes
|
||||
source-map-0.8.0 930248 bytes
|
||||
Smallest memory usage is local code
|
||||
|
||||
Encode speed:
|
||||
encode: local code x 8,013 ops/sec ±0.19% (100 runs sampled)
|
||||
encode: @jridgewell/sourcemap-codec 1.4.15 x 7,989 ops/sec ±0.20% (101 runs sampled)
|
||||
encode: sourcemap-codec x 2,472 ops/sec ±0.21% (99 runs sampled)
|
||||
encode: source-map-0.6.1 x 2,200 ops/sec ±0.17% (99 runs sampled)
|
||||
encode: source-map-0.8.0 x 2,220 ops/sec ±0.37% (99 runs sampled)
|
||||
Fastest is encode: local code
|
||||
|
||||
|
||||
***
|
||||
|
||||
|
||||
vscode.map - 2141001 segments
|
||||
|
||||
Decode Memory Usage:
|
||||
local code 198955264 bytes
|
||||
@jridgewell/sourcemap-codec 1.4.15 199175352 bytes
|
||||
sourcemap-codec 199102688 bytes
|
||||
source-map-0.6.1 386323432 bytes
|
||||
source-map-0.8.0 244116432 bytes
|
||||
chrome dev tools 293734280 bytes
|
||||
Smallest memory usage is local code
|
||||
|
||||
Decode speed:
|
||||
decode: local code x 3.90 ops/sec ±22.21% (15 runs sampled)
|
||||
decode: @jridgewell/sourcemap-codec 1.4.15 x 3.95 ops/sec ±23.53% (15 runs sampled)
|
||||
decode: sourcemap-codec x 3.82 ops/sec ±17.94% (14 runs sampled)
|
||||
decode: source-map-0.6.1 x 0.61 ops/sec ±7.81% (6 runs sampled)
|
||||
decode: source-map-0.8.0 x 9.54 ops/sec ±0.28% (28 runs sampled)
|
||||
chrome dev tools x 2.18 ops/sec ±10.58% (10 runs sampled)
|
||||
Fastest is decode: source-map-0.8.0
|
||||
|
||||
Encode Memory Usage:
|
||||
local code 13509880 bytes
|
||||
@jridgewell/sourcemap-codec 1.4.15 13537648 bytes
|
||||
sourcemap-codec 32540104 bytes
|
||||
source-map-0.6.1 127531040 bytes
|
||||
source-map-0.8.0 127535312 bytes
|
||||
Smallest memory usage is local code
|
||||
|
||||
Encode speed:
|
||||
encode: local code x 20.10 ops/sec ±0.19% (38 runs sampled)
|
||||
encode: @jridgewell/sourcemap-codec 1.4.15 x 20.26 ops/sec ±0.32% (38 runs sampled)
|
||||
encode: sourcemap-codec x 5.44 ops/sec ±1.64% (18 runs sampled)
|
||||
encode: source-map-0.6.1 x 2.30 ops/sec ±4.79% (10 runs sampled)
|
||||
encode: source-map-0.8.0 x 2.46 ops/sec ±6.53% (10 runs sampled)
|
||||
Fastest is encode: @jridgewell/sourcemap-codec 1.4.15
|
||||
```
|
||||
|
||||
# License
|
||||
|
||||
MIT
|
||||
423
backend/node_modules/@jridgewell/sourcemap-codec/dist/sourcemap-codec.mjs
generated
vendored
Normal file
423
backend/node_modules/@jridgewell/sourcemap-codec/dist/sourcemap-codec.mjs
generated
vendored
Normal file
@ -0,0 +1,423 @@
|
||||
// src/vlq.ts
|
||||
var comma = ",".charCodeAt(0);
|
||||
var semicolon = ";".charCodeAt(0);
|
||||
var chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
|
||||
var intToChar = new Uint8Array(64);
|
||||
var charToInt = new Uint8Array(128);
|
||||
for (let i = 0; i < chars.length; i++) {
|
||||
const c = chars.charCodeAt(i);
|
||||
intToChar[i] = c;
|
||||
charToInt[c] = i;
|
||||
}
|
||||
function decodeInteger(reader, relative) {
|
||||
let value = 0;
|
||||
let shift = 0;
|
||||
let integer = 0;
|
||||
do {
|
||||
const c = reader.next();
|
||||
integer = charToInt[c];
|
||||
value |= (integer & 31) << shift;
|
||||
shift += 5;
|
||||
} while (integer & 32);
|
||||
const shouldNegate = value & 1;
|
||||
value >>>= 1;
|
||||
if (shouldNegate) {
|
||||
value = -2147483648 | -value;
|
||||
}
|
||||
return relative + value;
|
||||
}
|
||||
function encodeInteger(builder, num, relative) {
|
||||
let delta = num - relative;
|
||||
delta = delta < 0 ? -delta << 1 | 1 : delta << 1;
|
||||
do {
|
||||
let clamped = delta & 31;
|
||||
delta >>>= 5;
|
||||
if (delta > 0) clamped |= 32;
|
||||
builder.write(intToChar[clamped]);
|
||||
} while (delta > 0);
|
||||
return num;
|
||||
}
|
||||
function hasMoreVlq(reader, max) {
|
||||
if (reader.pos >= max) return false;
|
||||
return reader.peek() !== comma;
|
||||
}
|
||||
|
||||
// src/strings.ts
|
||||
var bufLength = 1024 * 16;
|
||||
var td = typeof TextDecoder !== "undefined" ? /* @__PURE__ */ new TextDecoder() : typeof Buffer !== "undefined" ? {
|
||||
decode(buf) {
|
||||
const out = Buffer.from(buf.buffer, buf.byteOffset, buf.byteLength);
|
||||
return out.toString();
|
||||
}
|
||||
} : {
|
||||
decode(buf) {
|
||||
let out = "";
|
||||
for (let i = 0; i < buf.length; i++) {
|
||||
out += String.fromCharCode(buf[i]);
|
||||
}
|
||||
return out;
|
||||
}
|
||||
};
|
||||
var StringWriter = class {
|
||||
constructor() {
|
||||
this.pos = 0;
|
||||
this.out = "";
|
||||
this.buffer = new Uint8Array(bufLength);
|
||||
}
|
||||
write(v) {
|
||||
const { buffer } = this;
|
||||
buffer[this.pos++] = v;
|
||||
if (this.pos === bufLength) {
|
||||
this.out += td.decode(buffer);
|
||||
this.pos = 0;
|
||||
}
|
||||
}
|
||||
flush() {
|
||||
const { buffer, out, pos } = this;
|
||||
return pos > 0 ? out + td.decode(buffer.subarray(0, pos)) : out;
|
||||
}
|
||||
};
|
||||
var StringReader = class {
|
||||
constructor(buffer) {
|
||||
this.pos = 0;
|
||||
this.buffer = buffer;
|
||||
}
|
||||
next() {
|
||||
return this.buffer.charCodeAt(this.pos++);
|
||||
}
|
||||
peek() {
|
||||
return this.buffer.charCodeAt(this.pos);
|
||||
}
|
||||
indexOf(char) {
|
||||
const { buffer, pos } = this;
|
||||
const idx = buffer.indexOf(char, pos);
|
||||
return idx === -1 ? buffer.length : idx;
|
||||
}
|
||||
};
|
||||
|
||||
// src/scopes.ts
|
||||
var EMPTY = [];
|
||||
function decodeOriginalScopes(input) {
|
||||
const { length } = input;
|
||||
const reader = new StringReader(input);
|
||||
const scopes = [];
|
||||
const stack = [];
|
||||
let line = 0;
|
||||
for (; reader.pos < length; reader.pos++) {
|
||||
line = decodeInteger(reader, line);
|
||||
const column = decodeInteger(reader, 0);
|
||||
if (!hasMoreVlq(reader, length)) {
|
||||
const last = stack.pop();
|
||||
last[2] = line;
|
||||
last[3] = column;
|
||||
continue;
|
||||
}
|
||||
const kind = decodeInteger(reader, 0);
|
||||
const fields = decodeInteger(reader, 0);
|
||||
const hasName = fields & 1;
|
||||
const scope = hasName ? [line, column, 0, 0, kind, decodeInteger(reader, 0)] : [line, column, 0, 0, kind];
|
||||
let vars = EMPTY;
|
||||
if (hasMoreVlq(reader, length)) {
|
||||
vars = [];
|
||||
do {
|
||||
const varsIndex = decodeInteger(reader, 0);
|
||||
vars.push(varsIndex);
|
||||
} while (hasMoreVlq(reader, length));
|
||||
}
|
||||
scope.vars = vars;
|
||||
scopes.push(scope);
|
||||
stack.push(scope);
|
||||
}
|
||||
return scopes;
|
||||
}
|
||||
function encodeOriginalScopes(scopes) {
|
||||
const writer = new StringWriter();
|
||||
for (let i = 0; i < scopes.length; ) {
|
||||
i = _encodeOriginalScopes(scopes, i, writer, [0]);
|
||||
}
|
||||
return writer.flush();
|
||||
}
|
||||
function _encodeOriginalScopes(scopes, index, writer, state) {
|
||||
const scope = scopes[index];
|
||||
const { 0: startLine, 1: startColumn, 2: endLine, 3: endColumn, 4: kind, vars } = scope;
|
||||
if (index > 0) writer.write(comma);
|
||||
state[0] = encodeInteger(writer, startLine, state[0]);
|
||||
encodeInteger(writer, startColumn, 0);
|
||||
encodeInteger(writer, kind, 0);
|
||||
const fields = scope.length === 6 ? 1 : 0;
|
||||
encodeInteger(writer, fields, 0);
|
||||
if (scope.length === 6) encodeInteger(writer, scope[5], 0);
|
||||
for (const v of vars) {
|
||||
encodeInteger(writer, v, 0);
|
||||
}
|
||||
for (index++; index < scopes.length; ) {
|
||||
const next = scopes[index];
|
||||
const { 0: l, 1: c } = next;
|
||||
if (l > endLine || l === endLine && c >= endColumn) {
|
||||
break;
|
||||
}
|
||||
index = _encodeOriginalScopes(scopes, index, writer, state);
|
||||
}
|
||||
writer.write(comma);
|
||||
state[0] = encodeInteger(writer, endLine, state[0]);
|
||||
encodeInteger(writer, endColumn, 0);
|
||||
return index;
|
||||
}
|
||||
function decodeGeneratedRanges(input) {
|
||||
const { length } = input;
|
||||
const reader = new StringReader(input);
|
||||
const ranges = [];
|
||||
const stack = [];
|
||||
let genLine = 0;
|
||||
let definitionSourcesIndex = 0;
|
||||
let definitionScopeIndex = 0;
|
||||
let callsiteSourcesIndex = 0;
|
||||
let callsiteLine = 0;
|
||||
let callsiteColumn = 0;
|
||||
let bindingLine = 0;
|
||||
let bindingColumn = 0;
|
||||
do {
|
||||
const semi = reader.indexOf(";");
|
||||
let genColumn = 0;
|
||||
for (; reader.pos < semi; reader.pos++) {
|
||||
genColumn = decodeInteger(reader, genColumn);
|
||||
if (!hasMoreVlq(reader, semi)) {
|
||||
const last = stack.pop();
|
||||
last[2] = genLine;
|
||||
last[3] = genColumn;
|
||||
continue;
|
||||
}
|
||||
const fields = decodeInteger(reader, 0);
|
||||
const hasDefinition = fields & 1;
|
||||
const hasCallsite = fields & 2;
|
||||
const hasScope = fields & 4;
|
||||
let callsite = null;
|
||||
let bindings = EMPTY;
|
||||
let range;
|
||||
if (hasDefinition) {
|
||||
const defSourcesIndex = decodeInteger(reader, definitionSourcesIndex);
|
||||
definitionScopeIndex = decodeInteger(
|
||||
reader,
|
||||
definitionSourcesIndex === defSourcesIndex ? definitionScopeIndex : 0
|
||||
);
|
||||
definitionSourcesIndex = defSourcesIndex;
|
||||
range = [genLine, genColumn, 0, 0, defSourcesIndex, definitionScopeIndex];
|
||||
} else {
|
||||
range = [genLine, genColumn, 0, 0];
|
||||
}
|
||||
range.isScope = !!hasScope;
|
||||
if (hasCallsite) {
|
||||
const prevCsi = callsiteSourcesIndex;
|
||||
const prevLine = callsiteLine;
|
||||
callsiteSourcesIndex = decodeInteger(reader, callsiteSourcesIndex);
|
||||
const sameSource = prevCsi === callsiteSourcesIndex;
|
||||
callsiteLine = decodeInteger(reader, sameSource ? callsiteLine : 0);
|
||||
callsiteColumn = decodeInteger(
|
||||
reader,
|
||||
sameSource && prevLine === callsiteLine ? callsiteColumn : 0
|
||||
);
|
||||
callsite = [callsiteSourcesIndex, callsiteLine, callsiteColumn];
|
||||
}
|
||||
range.callsite = callsite;
|
||||
if (hasMoreVlq(reader, semi)) {
|
||||
bindings = [];
|
||||
do {
|
||||
bindingLine = genLine;
|
||||
bindingColumn = genColumn;
|
||||
const expressionsCount = decodeInteger(reader, 0);
|
||||
let expressionRanges;
|
||||
if (expressionsCount < -1) {
|
||||
expressionRanges = [[decodeInteger(reader, 0)]];
|
||||
for (let i = -1; i > expressionsCount; i--) {
|
||||
const prevBl = bindingLine;
|
||||
bindingLine = decodeInteger(reader, bindingLine);
|
||||
bindingColumn = decodeInteger(reader, bindingLine === prevBl ? bindingColumn : 0);
|
||||
const expression = decodeInteger(reader, 0);
|
||||
expressionRanges.push([expression, bindingLine, bindingColumn]);
|
||||
}
|
||||
} else {
|
||||
expressionRanges = [[expressionsCount]];
|
||||
}
|
||||
bindings.push(expressionRanges);
|
||||
} while (hasMoreVlq(reader, semi));
|
||||
}
|
||||
range.bindings = bindings;
|
||||
ranges.push(range);
|
||||
stack.push(range);
|
||||
}
|
||||
genLine++;
|
||||
reader.pos = semi + 1;
|
||||
} while (reader.pos < length);
|
||||
return ranges;
|
||||
}
|
||||
function encodeGeneratedRanges(ranges) {
|
||||
if (ranges.length === 0) return "";
|
||||
const writer = new StringWriter();
|
||||
for (let i = 0; i < ranges.length; ) {
|
||||
i = _encodeGeneratedRanges(ranges, i, writer, [0, 0, 0, 0, 0, 0, 0]);
|
||||
}
|
||||
return writer.flush();
|
||||
}
|
||||
function _encodeGeneratedRanges(ranges, index, writer, state) {
|
||||
const range = ranges[index];
|
||||
const {
|
||||
0: startLine,
|
||||
1: startColumn,
|
||||
2: endLine,
|
||||
3: endColumn,
|
||||
isScope,
|
||||
callsite,
|
||||
bindings
|
||||
} = range;
|
||||
if (state[0] < startLine) {
|
||||
catchupLine(writer, state[0], startLine);
|
||||
state[0] = startLine;
|
||||
state[1] = 0;
|
||||
} else if (index > 0) {
|
||||
writer.write(comma);
|
||||
}
|
||||
state[1] = encodeInteger(writer, range[1], state[1]);
|
||||
const fields = (range.length === 6 ? 1 : 0) | (callsite ? 2 : 0) | (isScope ? 4 : 0);
|
||||
encodeInteger(writer, fields, 0);
|
||||
if (range.length === 6) {
|
||||
const { 4: sourcesIndex, 5: scopesIndex } = range;
|
||||
if (sourcesIndex !== state[2]) {
|
||||
state[3] = 0;
|
||||
}
|
||||
state[2] = encodeInteger(writer, sourcesIndex, state[2]);
|
||||
state[3] = encodeInteger(writer, scopesIndex, state[3]);
|
||||
}
|
||||
if (callsite) {
|
||||
const { 0: sourcesIndex, 1: callLine, 2: callColumn } = range.callsite;
|
||||
if (sourcesIndex !== state[4]) {
|
||||
state[5] = 0;
|
||||
state[6] = 0;
|
||||
} else if (callLine !== state[5]) {
|
||||
state[6] = 0;
|
||||
}
|
||||
state[4] = encodeInteger(writer, sourcesIndex, state[4]);
|
||||
state[5] = encodeInteger(writer, callLine, state[5]);
|
||||
state[6] = encodeInteger(writer, callColumn, state[6]);
|
||||
}
|
||||
if (bindings) {
|
||||
for (const binding of bindings) {
|
||||
if (binding.length > 1) encodeInteger(writer, -binding.length, 0);
|
||||
const expression = binding[0][0];
|
||||
encodeInteger(writer, expression, 0);
|
||||
let bindingStartLine = startLine;
|
||||
let bindingStartColumn = startColumn;
|
||||
for (let i = 1; i < binding.length; i++) {
|
||||
const expRange = binding[i];
|
||||
bindingStartLine = encodeInteger(writer, expRange[1], bindingStartLine);
|
||||
bindingStartColumn = encodeInteger(writer, expRange[2], bindingStartColumn);
|
||||
encodeInteger(writer, expRange[0], 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
for (index++; index < ranges.length; ) {
|
||||
const next = ranges[index];
|
||||
const { 0: l, 1: c } = next;
|
||||
if (l > endLine || l === endLine && c >= endColumn) {
|
||||
break;
|
||||
}
|
||||
index = _encodeGeneratedRanges(ranges, index, writer, state);
|
||||
}
|
||||
if (state[0] < endLine) {
|
||||
catchupLine(writer, state[0], endLine);
|
||||
state[0] = endLine;
|
||||
state[1] = 0;
|
||||
} else {
|
||||
writer.write(comma);
|
||||
}
|
||||
state[1] = encodeInteger(writer, endColumn, state[1]);
|
||||
return index;
|
||||
}
|
||||
function catchupLine(writer, lastLine, line) {
|
||||
do {
|
||||
writer.write(semicolon);
|
||||
} while (++lastLine < line);
|
||||
}
|
||||
|
||||
// src/sourcemap-codec.ts
|
||||
function decode(mappings) {
|
||||
const { length } = mappings;
|
||||
const reader = new StringReader(mappings);
|
||||
const decoded = [];
|
||||
let genColumn = 0;
|
||||
let sourcesIndex = 0;
|
||||
let sourceLine = 0;
|
||||
let sourceColumn = 0;
|
||||
let namesIndex = 0;
|
||||
do {
|
||||
const semi = reader.indexOf(";");
|
||||
const line = [];
|
||||
let sorted = true;
|
||||
let lastCol = 0;
|
||||
genColumn = 0;
|
||||
while (reader.pos < semi) {
|
||||
let seg;
|
||||
genColumn = decodeInteger(reader, genColumn);
|
||||
if (genColumn < lastCol) sorted = false;
|
||||
lastCol = genColumn;
|
||||
if (hasMoreVlq(reader, semi)) {
|
||||
sourcesIndex = decodeInteger(reader, sourcesIndex);
|
||||
sourceLine = decodeInteger(reader, sourceLine);
|
||||
sourceColumn = decodeInteger(reader, sourceColumn);
|
||||
if (hasMoreVlq(reader, semi)) {
|
||||
namesIndex = decodeInteger(reader, namesIndex);
|
||||
seg = [genColumn, sourcesIndex, sourceLine, sourceColumn, namesIndex];
|
||||
} else {
|
||||
seg = [genColumn, sourcesIndex, sourceLine, sourceColumn];
|
||||
}
|
||||
} else {
|
||||
seg = [genColumn];
|
||||
}
|
||||
line.push(seg);
|
||||
reader.pos++;
|
||||
}
|
||||
if (!sorted) sort(line);
|
||||
decoded.push(line);
|
||||
reader.pos = semi + 1;
|
||||
} while (reader.pos <= length);
|
||||
return decoded;
|
||||
}
|
||||
function sort(line) {
|
||||
line.sort(sortComparator);
|
||||
}
|
||||
function sortComparator(a, b) {
|
||||
return a[0] - b[0];
|
||||
}
|
||||
function encode(decoded) {
|
||||
const writer = new StringWriter();
|
||||
let sourcesIndex = 0;
|
||||
let sourceLine = 0;
|
||||
let sourceColumn = 0;
|
||||
let namesIndex = 0;
|
||||
for (let i = 0; i < decoded.length; i++) {
|
||||
const line = decoded[i];
|
||||
if (i > 0) writer.write(semicolon);
|
||||
if (line.length === 0) continue;
|
||||
let genColumn = 0;
|
||||
for (let j = 0; j < line.length; j++) {
|
||||
const segment = line[j];
|
||||
if (j > 0) writer.write(comma);
|
||||
genColumn = encodeInteger(writer, segment[0], genColumn);
|
||||
if (segment.length === 1) continue;
|
||||
sourcesIndex = encodeInteger(writer, segment[1], sourcesIndex);
|
||||
sourceLine = encodeInteger(writer, segment[2], sourceLine);
|
||||
sourceColumn = encodeInteger(writer, segment[3], sourceColumn);
|
||||
if (segment.length === 4) continue;
|
||||
namesIndex = encodeInteger(writer, segment[4], namesIndex);
|
||||
}
|
||||
}
|
||||
return writer.flush();
|
||||
}
|
||||
export {
|
||||
decode,
|
||||
decodeGeneratedRanges,
|
||||
decodeOriginalScopes,
|
||||
encode,
|
||||
encodeGeneratedRanges,
|
||||
encodeOriginalScopes
|
||||
};
|
||||
//# sourceMappingURL=sourcemap-codec.mjs.map
|
||||
6
backend/node_modules/@jridgewell/sourcemap-codec/dist/sourcemap-codec.mjs.map
generated
vendored
Normal file
6
backend/node_modules/@jridgewell/sourcemap-codec/dist/sourcemap-codec.mjs.map
generated
vendored
Normal file
File diff suppressed because one or more lines are too long
464
backend/node_modules/@jridgewell/sourcemap-codec/dist/sourcemap-codec.umd.js
generated
vendored
Normal file
464
backend/node_modules/@jridgewell/sourcemap-codec/dist/sourcemap-codec.umd.js
generated
vendored
Normal file
@ -0,0 +1,464 @@
|
||||
(function (global, factory) {
|
||||
if (typeof exports === 'object' && typeof module !== 'undefined') {
|
||||
factory(module);
|
||||
module.exports = def(module);
|
||||
} else if (typeof define === 'function' && define.amd) {
|
||||
define(['module'], function(mod) {
|
||||
factory.apply(this, arguments);
|
||||
mod.exports = def(mod);
|
||||
});
|
||||
} else {
|
||||
const mod = { exports: {} };
|
||||
factory(mod);
|
||||
global = typeof globalThis !== 'undefined' ? globalThis : global || self;
|
||||
global.sourcemapCodec = def(mod);
|
||||
}
|
||||
function def(m) { return 'default' in m.exports ? m.exports.default : m.exports; }
|
||||
})(this, (function (module) {
|
||||
"use strict";
|
||||
var __defProp = Object.defineProperty;
|
||||
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
||||
var __getOwnPropNames = Object.getOwnPropertyNames;
|
||||
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
||||
var __export = (target, all) => {
|
||||
for (var name in all)
|
||||
__defProp(target, name, { get: all[name], enumerable: true });
|
||||
};
|
||||
var __copyProps = (to, from, except, desc) => {
|
||||
if (from && typeof from === "object" || typeof from === "function") {
|
||||
for (let key of __getOwnPropNames(from))
|
||||
if (!__hasOwnProp.call(to, key) && key !== except)
|
||||
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
||||
}
|
||||
return to;
|
||||
};
|
||||
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
||||
|
||||
// src/sourcemap-codec.ts
|
||||
var sourcemap_codec_exports = {};
|
||||
__export(sourcemap_codec_exports, {
|
||||
decode: () => decode,
|
||||
decodeGeneratedRanges: () => decodeGeneratedRanges,
|
||||
decodeOriginalScopes: () => decodeOriginalScopes,
|
||||
encode: () => encode,
|
||||
encodeGeneratedRanges: () => encodeGeneratedRanges,
|
||||
encodeOriginalScopes: () => encodeOriginalScopes
|
||||
});
|
||||
module.exports = __toCommonJS(sourcemap_codec_exports);
|
||||
|
||||
// src/vlq.ts
|
||||
var comma = ",".charCodeAt(0);
|
||||
var semicolon = ";".charCodeAt(0);
|
||||
var chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
|
||||
var intToChar = new Uint8Array(64);
|
||||
var charToInt = new Uint8Array(128);
|
||||
for (let i = 0; i < chars.length; i++) {
|
||||
const c = chars.charCodeAt(i);
|
||||
intToChar[i] = c;
|
||||
charToInt[c] = i;
|
||||
}
|
||||
function decodeInteger(reader, relative) {
|
||||
let value = 0;
|
||||
let shift = 0;
|
||||
let integer = 0;
|
||||
do {
|
||||
const c = reader.next();
|
||||
integer = charToInt[c];
|
||||
value |= (integer & 31) << shift;
|
||||
shift += 5;
|
||||
} while (integer & 32);
|
||||
const shouldNegate = value & 1;
|
||||
value >>>= 1;
|
||||
if (shouldNegate) {
|
||||
value = -2147483648 | -value;
|
||||
}
|
||||
return relative + value;
|
||||
}
|
||||
function encodeInteger(builder, num, relative) {
|
||||
let delta = num - relative;
|
||||
delta = delta < 0 ? -delta << 1 | 1 : delta << 1;
|
||||
do {
|
||||
let clamped = delta & 31;
|
||||
delta >>>= 5;
|
||||
if (delta > 0) clamped |= 32;
|
||||
builder.write(intToChar[clamped]);
|
||||
} while (delta > 0);
|
||||
return num;
|
||||
}
|
||||
function hasMoreVlq(reader, max) {
|
||||
if (reader.pos >= max) return false;
|
||||
return reader.peek() !== comma;
|
||||
}
|
||||
|
||||
// src/strings.ts
|
||||
var bufLength = 1024 * 16;
|
||||
var td = typeof TextDecoder !== "undefined" ? /* @__PURE__ */ new TextDecoder() : typeof Buffer !== "undefined" ? {
|
||||
decode(buf) {
|
||||
const out = Buffer.from(buf.buffer, buf.byteOffset, buf.byteLength);
|
||||
return out.toString();
|
||||
}
|
||||
} : {
|
||||
decode(buf) {
|
||||
let out = "";
|
||||
for (let i = 0; i < buf.length; i++) {
|
||||
out += String.fromCharCode(buf[i]);
|
||||
}
|
||||
return out;
|
||||
}
|
||||
};
|
||||
var StringWriter = class {
|
||||
constructor() {
|
||||
this.pos = 0;
|
||||
this.out = "";
|
||||
this.buffer = new Uint8Array(bufLength);
|
||||
}
|
||||
write(v) {
|
||||
const { buffer } = this;
|
||||
buffer[this.pos++] = v;
|
||||
if (this.pos === bufLength) {
|
||||
this.out += td.decode(buffer);
|
||||
this.pos = 0;
|
||||
}
|
||||
}
|
||||
flush() {
|
||||
const { buffer, out, pos } = this;
|
||||
return pos > 0 ? out + td.decode(buffer.subarray(0, pos)) : out;
|
||||
}
|
||||
};
|
||||
var StringReader = class {
|
||||
constructor(buffer) {
|
||||
this.pos = 0;
|
||||
this.buffer = buffer;
|
||||
}
|
||||
next() {
|
||||
return this.buffer.charCodeAt(this.pos++);
|
||||
}
|
||||
peek() {
|
||||
return this.buffer.charCodeAt(this.pos);
|
||||
}
|
||||
indexOf(char) {
|
||||
const { buffer, pos } = this;
|
||||
const idx = buffer.indexOf(char, pos);
|
||||
return idx === -1 ? buffer.length : idx;
|
||||
}
|
||||
};
|
||||
|
||||
// src/scopes.ts
|
||||
var EMPTY = [];
|
||||
function decodeOriginalScopes(input) {
|
||||
const { length } = input;
|
||||
const reader = new StringReader(input);
|
||||
const scopes = [];
|
||||
const stack = [];
|
||||
let line = 0;
|
||||
for (; reader.pos < length; reader.pos++) {
|
||||
line = decodeInteger(reader, line);
|
||||
const column = decodeInteger(reader, 0);
|
||||
if (!hasMoreVlq(reader, length)) {
|
||||
const last = stack.pop();
|
||||
last[2] = line;
|
||||
last[3] = column;
|
||||
continue;
|
||||
}
|
||||
const kind = decodeInteger(reader, 0);
|
||||
const fields = decodeInteger(reader, 0);
|
||||
const hasName = fields & 1;
|
||||
const scope = hasName ? [line, column, 0, 0, kind, decodeInteger(reader, 0)] : [line, column, 0, 0, kind];
|
||||
let vars = EMPTY;
|
||||
if (hasMoreVlq(reader, length)) {
|
||||
vars = [];
|
||||
do {
|
||||
const varsIndex = decodeInteger(reader, 0);
|
||||
vars.push(varsIndex);
|
||||
} while (hasMoreVlq(reader, length));
|
||||
}
|
||||
scope.vars = vars;
|
||||
scopes.push(scope);
|
||||
stack.push(scope);
|
||||
}
|
||||
return scopes;
|
||||
}
|
||||
function encodeOriginalScopes(scopes) {
|
||||
const writer = new StringWriter();
|
||||
for (let i = 0; i < scopes.length; ) {
|
||||
i = _encodeOriginalScopes(scopes, i, writer, [0]);
|
||||
}
|
||||
return writer.flush();
|
||||
}
|
||||
function _encodeOriginalScopes(scopes, index, writer, state) {
|
||||
const scope = scopes[index];
|
||||
const { 0: startLine, 1: startColumn, 2: endLine, 3: endColumn, 4: kind, vars } = scope;
|
||||
if (index > 0) writer.write(comma);
|
||||
state[0] = encodeInteger(writer, startLine, state[0]);
|
||||
encodeInteger(writer, startColumn, 0);
|
||||
encodeInteger(writer, kind, 0);
|
||||
const fields = scope.length === 6 ? 1 : 0;
|
||||
encodeInteger(writer, fields, 0);
|
||||
if (scope.length === 6) encodeInteger(writer, scope[5], 0);
|
||||
for (const v of vars) {
|
||||
encodeInteger(writer, v, 0);
|
||||
}
|
||||
for (index++; index < scopes.length; ) {
|
||||
const next = scopes[index];
|
||||
const { 0: l, 1: c } = next;
|
||||
if (l > endLine || l === endLine && c >= endColumn) {
|
||||
break;
|
||||
}
|
||||
index = _encodeOriginalScopes(scopes, index, writer, state);
|
||||
}
|
||||
writer.write(comma);
|
||||
state[0] = encodeInteger(writer, endLine, state[0]);
|
||||
encodeInteger(writer, endColumn, 0);
|
||||
return index;
|
||||
}
|
||||
function decodeGeneratedRanges(input) {
|
||||
const { length } = input;
|
||||
const reader = new StringReader(input);
|
||||
const ranges = [];
|
||||
const stack = [];
|
||||
let genLine = 0;
|
||||
let definitionSourcesIndex = 0;
|
||||
let definitionScopeIndex = 0;
|
||||
let callsiteSourcesIndex = 0;
|
||||
let callsiteLine = 0;
|
||||
let callsiteColumn = 0;
|
||||
let bindingLine = 0;
|
||||
let bindingColumn = 0;
|
||||
do {
|
||||
const semi = reader.indexOf(";");
|
||||
let genColumn = 0;
|
||||
for (; reader.pos < semi; reader.pos++) {
|
||||
genColumn = decodeInteger(reader, genColumn);
|
||||
if (!hasMoreVlq(reader, semi)) {
|
||||
const last = stack.pop();
|
||||
last[2] = genLine;
|
||||
last[3] = genColumn;
|
||||
continue;
|
||||
}
|
||||
const fields = decodeInteger(reader, 0);
|
||||
const hasDefinition = fields & 1;
|
||||
const hasCallsite = fields & 2;
|
||||
const hasScope = fields & 4;
|
||||
let callsite = null;
|
||||
let bindings = EMPTY;
|
||||
let range;
|
||||
if (hasDefinition) {
|
||||
const defSourcesIndex = decodeInteger(reader, definitionSourcesIndex);
|
||||
definitionScopeIndex = decodeInteger(
|
||||
reader,
|
||||
definitionSourcesIndex === defSourcesIndex ? definitionScopeIndex : 0
|
||||
);
|
||||
definitionSourcesIndex = defSourcesIndex;
|
||||
range = [genLine, genColumn, 0, 0, defSourcesIndex, definitionScopeIndex];
|
||||
} else {
|
||||
range = [genLine, genColumn, 0, 0];
|
||||
}
|
||||
range.isScope = !!hasScope;
|
||||
if (hasCallsite) {
|
||||
const prevCsi = callsiteSourcesIndex;
|
||||
const prevLine = callsiteLine;
|
||||
callsiteSourcesIndex = decodeInteger(reader, callsiteSourcesIndex);
|
||||
const sameSource = prevCsi === callsiteSourcesIndex;
|
||||
callsiteLine = decodeInteger(reader, sameSource ? callsiteLine : 0);
|
||||
callsiteColumn = decodeInteger(
|
||||
reader,
|
||||
sameSource && prevLine === callsiteLine ? callsiteColumn : 0
|
||||
);
|
||||
callsite = [callsiteSourcesIndex, callsiteLine, callsiteColumn];
|
||||
}
|
||||
range.callsite = callsite;
|
||||
if (hasMoreVlq(reader, semi)) {
|
||||
bindings = [];
|
||||
do {
|
||||
bindingLine = genLine;
|
||||
bindingColumn = genColumn;
|
||||
const expressionsCount = decodeInteger(reader, 0);
|
||||
let expressionRanges;
|
||||
if (expressionsCount < -1) {
|
||||
expressionRanges = [[decodeInteger(reader, 0)]];
|
||||
for (let i = -1; i > expressionsCount; i--) {
|
||||
const prevBl = bindingLine;
|
||||
bindingLine = decodeInteger(reader, bindingLine);
|
||||
bindingColumn = decodeInteger(reader, bindingLine === prevBl ? bindingColumn : 0);
|
||||
const expression = decodeInteger(reader, 0);
|
||||
expressionRanges.push([expression, bindingLine, bindingColumn]);
|
||||
}
|
||||
} else {
|
||||
expressionRanges = [[expressionsCount]];
|
||||
}
|
||||
bindings.push(expressionRanges);
|
||||
} while (hasMoreVlq(reader, semi));
|
||||
}
|
||||
range.bindings = bindings;
|
||||
ranges.push(range);
|
||||
stack.push(range);
|
||||
}
|
||||
genLine++;
|
||||
reader.pos = semi + 1;
|
||||
} while (reader.pos < length);
|
||||
return ranges;
|
||||
}
|
||||
function encodeGeneratedRanges(ranges) {
|
||||
if (ranges.length === 0) return "";
|
||||
const writer = new StringWriter();
|
||||
for (let i = 0; i < ranges.length; ) {
|
||||
i = _encodeGeneratedRanges(ranges, i, writer, [0, 0, 0, 0, 0, 0, 0]);
|
||||
}
|
||||
return writer.flush();
|
||||
}
|
||||
function _encodeGeneratedRanges(ranges, index, writer, state) {
|
||||
const range = ranges[index];
|
||||
const {
|
||||
0: startLine,
|
||||
1: startColumn,
|
||||
2: endLine,
|
||||
3: endColumn,
|
||||
isScope,
|
||||
callsite,
|
||||
bindings
|
||||
} = range;
|
||||
if (state[0] < startLine) {
|
||||
catchupLine(writer, state[0], startLine);
|
||||
state[0] = startLine;
|
||||
state[1] = 0;
|
||||
} else if (index > 0) {
|
||||
writer.write(comma);
|
||||
}
|
||||
state[1] = encodeInteger(writer, range[1], state[1]);
|
||||
const fields = (range.length === 6 ? 1 : 0) | (callsite ? 2 : 0) | (isScope ? 4 : 0);
|
||||
encodeInteger(writer, fields, 0);
|
||||
if (range.length === 6) {
|
||||
const { 4: sourcesIndex, 5: scopesIndex } = range;
|
||||
if (sourcesIndex !== state[2]) {
|
||||
state[3] = 0;
|
||||
}
|
||||
state[2] = encodeInteger(writer, sourcesIndex, state[2]);
|
||||
state[3] = encodeInteger(writer, scopesIndex, state[3]);
|
||||
}
|
||||
if (callsite) {
|
||||
const { 0: sourcesIndex, 1: callLine, 2: callColumn } = range.callsite;
|
||||
if (sourcesIndex !== state[4]) {
|
||||
state[5] = 0;
|
||||
state[6] = 0;
|
||||
} else if (callLine !== state[5]) {
|
||||
state[6] = 0;
|
||||
}
|
||||
state[4] = encodeInteger(writer, sourcesIndex, state[4]);
|
||||
state[5] = encodeInteger(writer, callLine, state[5]);
|
||||
state[6] = encodeInteger(writer, callColumn, state[6]);
|
||||
}
|
||||
if (bindings) {
|
||||
for (const binding of bindings) {
|
||||
if (binding.length > 1) encodeInteger(writer, -binding.length, 0);
|
||||
const expression = binding[0][0];
|
||||
encodeInteger(writer, expression, 0);
|
||||
let bindingStartLine = startLine;
|
||||
let bindingStartColumn = startColumn;
|
||||
for (let i = 1; i < binding.length; i++) {
|
||||
const expRange = binding[i];
|
||||
bindingStartLine = encodeInteger(writer, expRange[1], bindingStartLine);
|
||||
bindingStartColumn = encodeInteger(writer, expRange[2], bindingStartColumn);
|
||||
encodeInteger(writer, expRange[0], 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
for (index++; index < ranges.length; ) {
|
||||
const next = ranges[index];
|
||||
const { 0: l, 1: c } = next;
|
||||
if (l > endLine || l === endLine && c >= endColumn) {
|
||||
break;
|
||||
}
|
||||
index = _encodeGeneratedRanges(ranges, index, writer, state);
|
||||
}
|
||||
if (state[0] < endLine) {
|
||||
catchupLine(writer, state[0], endLine);
|
||||
state[0] = endLine;
|
||||
state[1] = 0;
|
||||
} else {
|
||||
writer.write(comma);
|
||||
}
|
||||
state[1] = encodeInteger(writer, endColumn, state[1]);
|
||||
return index;
|
||||
}
|
||||
function catchupLine(writer, lastLine, line) {
|
||||
do {
|
||||
writer.write(semicolon);
|
||||
} while (++lastLine < line);
|
||||
}
|
||||
|
||||
// src/sourcemap-codec.ts
|
||||
function decode(mappings) {
|
||||
const { length } = mappings;
|
||||
const reader = new StringReader(mappings);
|
||||
const decoded = [];
|
||||
let genColumn = 0;
|
||||
let sourcesIndex = 0;
|
||||
let sourceLine = 0;
|
||||
let sourceColumn = 0;
|
||||
let namesIndex = 0;
|
||||
do {
|
||||
const semi = reader.indexOf(";");
|
||||
const line = [];
|
||||
let sorted = true;
|
||||
let lastCol = 0;
|
||||
genColumn = 0;
|
||||
while (reader.pos < semi) {
|
||||
let seg;
|
||||
genColumn = decodeInteger(reader, genColumn);
|
||||
if (genColumn < lastCol) sorted = false;
|
||||
lastCol = genColumn;
|
||||
if (hasMoreVlq(reader, semi)) {
|
||||
sourcesIndex = decodeInteger(reader, sourcesIndex);
|
||||
sourceLine = decodeInteger(reader, sourceLine);
|
||||
sourceColumn = decodeInteger(reader, sourceColumn);
|
||||
if (hasMoreVlq(reader, semi)) {
|
||||
namesIndex = decodeInteger(reader, namesIndex);
|
||||
seg = [genColumn, sourcesIndex, sourceLine, sourceColumn, namesIndex];
|
||||
} else {
|
||||
seg = [genColumn, sourcesIndex, sourceLine, sourceColumn];
|
||||
}
|
||||
} else {
|
||||
seg = [genColumn];
|
||||
}
|
||||
line.push(seg);
|
||||
reader.pos++;
|
||||
}
|
||||
if (!sorted) sort(line);
|
||||
decoded.push(line);
|
||||
reader.pos = semi + 1;
|
||||
} while (reader.pos <= length);
|
||||
return decoded;
|
||||
}
|
||||
function sort(line) {
|
||||
line.sort(sortComparator);
|
||||
}
|
||||
function sortComparator(a, b) {
|
||||
return a[0] - b[0];
|
||||
}
|
||||
function encode(decoded) {
|
||||
const writer = new StringWriter();
|
||||
let sourcesIndex = 0;
|
||||
let sourceLine = 0;
|
||||
let sourceColumn = 0;
|
||||
let namesIndex = 0;
|
||||
for (let i = 0; i < decoded.length; i++) {
|
||||
const line = decoded[i];
|
||||
if (i > 0) writer.write(semicolon);
|
||||
if (line.length === 0) continue;
|
||||
let genColumn = 0;
|
||||
for (let j = 0; j < line.length; j++) {
|
||||
const segment = line[j];
|
||||
if (j > 0) writer.write(comma);
|
||||
genColumn = encodeInteger(writer, segment[0], genColumn);
|
||||
if (segment.length === 1) continue;
|
||||
sourcesIndex = encodeInteger(writer, segment[1], sourcesIndex);
|
||||
sourceLine = encodeInteger(writer, segment[2], sourceLine);
|
||||
sourceColumn = encodeInteger(writer, segment[3], sourceColumn);
|
||||
if (segment.length === 4) continue;
|
||||
namesIndex = encodeInteger(writer, segment[4], namesIndex);
|
||||
}
|
||||
}
|
||||
return writer.flush();
|
||||
}
|
||||
}));
|
||||
//# sourceMappingURL=sourcemap-codec.umd.js.map
|
||||
6
backend/node_modules/@jridgewell/sourcemap-codec/dist/sourcemap-codec.umd.js.map
generated
vendored
Normal file
6
backend/node_modules/@jridgewell/sourcemap-codec/dist/sourcemap-codec.umd.js.map
generated
vendored
Normal file
File diff suppressed because one or more lines are too long
63
backend/node_modules/@jridgewell/sourcemap-codec/package.json
generated
vendored
Normal file
63
backend/node_modules/@jridgewell/sourcemap-codec/package.json
generated
vendored
Normal file
@ -0,0 +1,63 @@
|
||||
{
|
||||
"name": "@jridgewell/sourcemap-codec",
|
||||
"version": "1.5.5",
|
||||
"description": "Encode/decode sourcemap mappings",
|
||||
"keywords": [
|
||||
"sourcemap",
|
||||
"vlq"
|
||||
],
|
||||
"main": "dist/sourcemap-codec.umd.js",
|
||||
"module": "dist/sourcemap-codec.mjs",
|
||||
"types": "types/sourcemap-codec.d.cts",
|
||||
"files": [
|
||||
"dist",
|
||||
"src",
|
||||
"types"
|
||||
],
|
||||
"exports": {
|
||||
".": [
|
||||
{
|
||||
"import": {
|
||||
"types": "./types/sourcemap-codec.d.mts",
|
||||
"default": "./dist/sourcemap-codec.mjs"
|
||||
},
|
||||
"default": {
|
||||
"types": "./types/sourcemap-codec.d.cts",
|
||||
"default": "./dist/sourcemap-codec.umd.js"
|
||||
}
|
||||
},
|
||||
"./dist/sourcemap-codec.umd.js"
|
||||
],
|
||||
"./package.json": "./package.json"
|
||||
},
|
||||
"scripts": {
|
||||
"benchmark": "run-s build:code benchmark:*",
|
||||
"benchmark:install": "cd benchmark && npm install",
|
||||
"benchmark:only": "node --expose-gc benchmark/index.js",
|
||||
"build": "run-s -n build:code build:types",
|
||||
"build:code": "node ../../esbuild.mjs sourcemap-codec.ts",
|
||||
"build:types": "run-s build:types:force build:types:emit build:types:mts",
|
||||
"build:types:force": "rimraf tsconfig.build.tsbuildinfo",
|
||||
"build:types:emit": "tsc --project tsconfig.build.json",
|
||||
"build:types:mts": "node ../../mts-types.mjs",
|
||||
"clean": "run-s -n clean:code clean:types",
|
||||
"clean:code": "tsc --build --clean tsconfig.build.json",
|
||||
"clean:types": "rimraf dist types",
|
||||
"test": "run-s -n test:types test:only test:format",
|
||||
"test:format": "prettier --check '{src,test}/**/*.ts'",
|
||||
"test:only": "mocha",
|
||||
"test:types": "eslint '{src,test}/**/*.ts'",
|
||||
"lint": "run-s -n lint:types lint:format",
|
||||
"lint:format": "npm run test:format -- --write",
|
||||
"lint:types": "npm run test:types -- --fix",
|
||||
"prepublishOnly": "npm run-s -n build test"
|
||||
},
|
||||
"homepage": "https://github.com/jridgewell/sourcemaps/tree/main/packages/sourcemap-codec",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git+https://github.com/jridgewell/sourcemaps.git",
|
||||
"directory": "packages/sourcemap-codec"
|
||||
},
|
||||
"author": "Justin Ridgewell <justin@ridgewell.name>",
|
||||
"license": "MIT"
|
||||
}
|
||||
345
backend/node_modules/@jridgewell/sourcemap-codec/src/scopes.ts
generated
vendored
Normal file
345
backend/node_modules/@jridgewell/sourcemap-codec/src/scopes.ts
generated
vendored
Normal file
@ -0,0 +1,345 @@
|
||||
import { StringReader, StringWriter } from './strings';
|
||||
import { comma, decodeInteger, encodeInteger, hasMoreVlq, semicolon } from './vlq';
|
||||
|
||||
const EMPTY: any[] = [];
|
||||
|
||||
type Line = number;
|
||||
type Column = number;
|
||||
type Kind = number;
|
||||
type Name = number;
|
||||
type Var = number;
|
||||
type SourcesIndex = number;
|
||||
type ScopesIndex = number;
|
||||
|
||||
type Mix<A, B, O> = (A & O) | (B & O);
|
||||
|
||||
export type OriginalScope = Mix<
|
||||
[Line, Column, Line, Column, Kind],
|
||||
[Line, Column, Line, Column, Kind, Name],
|
||||
{ vars: Var[] }
|
||||
>;
|
||||
|
||||
export type GeneratedRange = Mix<
|
||||
[Line, Column, Line, Column],
|
||||
[Line, Column, Line, Column, SourcesIndex, ScopesIndex],
|
||||
{
|
||||
callsite: CallSite | null;
|
||||
bindings: Binding[];
|
||||
isScope: boolean;
|
||||
}
|
||||
>;
|
||||
export type CallSite = [SourcesIndex, Line, Column];
|
||||
type Binding = BindingExpressionRange[];
|
||||
export type BindingExpressionRange = [Name] | [Name, Line, Column];
|
||||
|
||||
export function decodeOriginalScopes(input: string): OriginalScope[] {
|
||||
const { length } = input;
|
||||
const reader = new StringReader(input);
|
||||
const scopes: OriginalScope[] = [];
|
||||
const stack: OriginalScope[] = [];
|
||||
let line = 0;
|
||||
|
||||
for (; reader.pos < length; reader.pos++) {
|
||||
line = decodeInteger(reader, line);
|
||||
const column = decodeInteger(reader, 0);
|
||||
|
||||
if (!hasMoreVlq(reader, length)) {
|
||||
const last = stack.pop()!;
|
||||
last[2] = line;
|
||||
last[3] = column;
|
||||
continue;
|
||||
}
|
||||
|
||||
const kind = decodeInteger(reader, 0);
|
||||
const fields = decodeInteger(reader, 0);
|
||||
const hasName = fields & 0b0001;
|
||||
|
||||
const scope: OriginalScope = (
|
||||
hasName ? [line, column, 0, 0, kind, decodeInteger(reader, 0)] : [line, column, 0, 0, kind]
|
||||
) as OriginalScope;
|
||||
|
||||
let vars: Var[] = EMPTY;
|
||||
if (hasMoreVlq(reader, length)) {
|
||||
vars = [];
|
||||
do {
|
||||
const varsIndex = decodeInteger(reader, 0);
|
||||
vars.push(varsIndex);
|
||||
} while (hasMoreVlq(reader, length));
|
||||
}
|
||||
scope.vars = vars;
|
||||
|
||||
scopes.push(scope);
|
||||
stack.push(scope);
|
||||
}
|
||||
|
||||
return scopes;
|
||||
}
|
||||
|
||||
export function encodeOriginalScopes(scopes: OriginalScope[]): string {
|
||||
const writer = new StringWriter();
|
||||
|
||||
for (let i = 0; i < scopes.length; ) {
|
||||
i = _encodeOriginalScopes(scopes, i, writer, [0]);
|
||||
}
|
||||
|
||||
return writer.flush();
|
||||
}
|
||||
|
||||
function _encodeOriginalScopes(
|
||||
scopes: OriginalScope[],
|
||||
index: number,
|
||||
writer: StringWriter,
|
||||
state: [
|
||||
number, // GenColumn
|
||||
],
|
||||
): number {
|
||||
const scope = scopes[index];
|
||||
const { 0: startLine, 1: startColumn, 2: endLine, 3: endColumn, 4: kind, vars } = scope;
|
||||
|
||||
if (index > 0) writer.write(comma);
|
||||
|
||||
state[0] = encodeInteger(writer, startLine, state[0]);
|
||||
encodeInteger(writer, startColumn, 0);
|
||||
encodeInteger(writer, kind, 0);
|
||||
|
||||
const fields = scope.length === 6 ? 0b0001 : 0;
|
||||
encodeInteger(writer, fields, 0);
|
||||
if (scope.length === 6) encodeInteger(writer, scope[5], 0);
|
||||
|
||||
for (const v of vars) {
|
||||
encodeInteger(writer, v, 0);
|
||||
}
|
||||
|
||||
for (index++; index < scopes.length; ) {
|
||||
const next = scopes[index];
|
||||
const { 0: l, 1: c } = next;
|
||||
if (l > endLine || (l === endLine && c >= endColumn)) {
|
||||
break;
|
||||
}
|
||||
index = _encodeOriginalScopes(scopes, index, writer, state);
|
||||
}
|
||||
|
||||
writer.write(comma);
|
||||
state[0] = encodeInteger(writer, endLine, state[0]);
|
||||
encodeInteger(writer, endColumn, 0);
|
||||
|
||||
return index;
|
||||
}
|
||||
|
||||
export function decodeGeneratedRanges(input: string): GeneratedRange[] {
|
||||
const { length } = input;
|
||||
const reader = new StringReader(input);
|
||||
const ranges: GeneratedRange[] = [];
|
||||
const stack: GeneratedRange[] = [];
|
||||
|
||||
let genLine = 0;
|
||||
let definitionSourcesIndex = 0;
|
||||
let definitionScopeIndex = 0;
|
||||
let callsiteSourcesIndex = 0;
|
||||
let callsiteLine = 0;
|
||||
let callsiteColumn = 0;
|
||||
let bindingLine = 0;
|
||||
let bindingColumn = 0;
|
||||
|
||||
do {
|
||||
const semi = reader.indexOf(';');
|
||||
let genColumn = 0;
|
||||
|
||||
for (; reader.pos < semi; reader.pos++) {
|
||||
genColumn = decodeInteger(reader, genColumn);
|
||||
|
||||
if (!hasMoreVlq(reader, semi)) {
|
||||
const last = stack.pop()!;
|
||||
last[2] = genLine;
|
||||
last[3] = genColumn;
|
||||
continue;
|
||||
}
|
||||
|
||||
const fields = decodeInteger(reader, 0);
|
||||
const hasDefinition = fields & 0b0001;
|
||||
const hasCallsite = fields & 0b0010;
|
||||
const hasScope = fields & 0b0100;
|
||||
|
||||
let callsite: CallSite | null = null;
|
||||
let bindings: Binding[] = EMPTY;
|
||||
let range: GeneratedRange;
|
||||
if (hasDefinition) {
|
||||
const defSourcesIndex = decodeInteger(reader, definitionSourcesIndex);
|
||||
definitionScopeIndex = decodeInteger(
|
||||
reader,
|
||||
definitionSourcesIndex === defSourcesIndex ? definitionScopeIndex : 0,
|
||||
);
|
||||
|
||||
definitionSourcesIndex = defSourcesIndex;
|
||||
range = [genLine, genColumn, 0, 0, defSourcesIndex, definitionScopeIndex] as GeneratedRange;
|
||||
} else {
|
||||
range = [genLine, genColumn, 0, 0] as GeneratedRange;
|
||||
}
|
||||
|
||||
range.isScope = !!hasScope;
|
||||
|
||||
if (hasCallsite) {
|
||||
const prevCsi = callsiteSourcesIndex;
|
||||
const prevLine = callsiteLine;
|
||||
callsiteSourcesIndex = decodeInteger(reader, callsiteSourcesIndex);
|
||||
const sameSource = prevCsi === callsiteSourcesIndex;
|
||||
callsiteLine = decodeInteger(reader, sameSource ? callsiteLine : 0);
|
||||
callsiteColumn = decodeInteger(
|
||||
reader,
|
||||
sameSource && prevLine === callsiteLine ? callsiteColumn : 0,
|
||||
);
|
||||
|
||||
callsite = [callsiteSourcesIndex, callsiteLine, callsiteColumn];
|
||||
}
|
||||
range.callsite = callsite;
|
||||
|
||||
if (hasMoreVlq(reader, semi)) {
|
||||
bindings = [];
|
||||
do {
|
||||
bindingLine = genLine;
|
||||
bindingColumn = genColumn;
|
||||
const expressionsCount = decodeInteger(reader, 0);
|
||||
let expressionRanges: BindingExpressionRange[];
|
||||
if (expressionsCount < -1) {
|
||||
expressionRanges = [[decodeInteger(reader, 0)]];
|
||||
for (let i = -1; i > expressionsCount; i--) {
|
||||
const prevBl = bindingLine;
|
||||
bindingLine = decodeInteger(reader, bindingLine);
|
||||
bindingColumn = decodeInteger(reader, bindingLine === prevBl ? bindingColumn : 0);
|
||||
const expression = decodeInteger(reader, 0);
|
||||
expressionRanges.push([expression, bindingLine, bindingColumn]);
|
||||
}
|
||||
} else {
|
||||
expressionRanges = [[expressionsCount]];
|
||||
}
|
||||
bindings.push(expressionRanges);
|
||||
} while (hasMoreVlq(reader, semi));
|
||||
}
|
||||
range.bindings = bindings;
|
||||
|
||||
ranges.push(range);
|
||||
stack.push(range);
|
||||
}
|
||||
|
||||
genLine++;
|
||||
reader.pos = semi + 1;
|
||||
} while (reader.pos < length);
|
||||
|
||||
return ranges;
|
||||
}
|
||||
|
||||
export function encodeGeneratedRanges(ranges: GeneratedRange[]): string {
|
||||
if (ranges.length === 0) return '';
|
||||
|
||||
const writer = new StringWriter();
|
||||
|
||||
for (let i = 0; i < ranges.length; ) {
|
||||
i = _encodeGeneratedRanges(ranges, i, writer, [0, 0, 0, 0, 0, 0, 0]);
|
||||
}
|
||||
|
||||
return writer.flush();
|
||||
}
|
||||
|
||||
function _encodeGeneratedRanges(
|
||||
ranges: GeneratedRange[],
|
||||
index: number,
|
||||
writer: StringWriter,
|
||||
state: [
|
||||
number, // GenLine
|
||||
number, // GenColumn
|
||||
number, // DefSourcesIndex
|
||||
number, // DefScopesIndex
|
||||
number, // CallSourcesIndex
|
||||
number, // CallLine
|
||||
number, // CallColumn
|
||||
],
|
||||
): number {
|
||||
const range = ranges[index];
|
||||
const {
|
||||
0: startLine,
|
||||
1: startColumn,
|
||||
2: endLine,
|
||||
3: endColumn,
|
||||
isScope,
|
||||
callsite,
|
||||
bindings,
|
||||
} = range;
|
||||
|
||||
if (state[0] < startLine) {
|
||||
catchupLine(writer, state[0], startLine);
|
||||
state[0] = startLine;
|
||||
state[1] = 0;
|
||||
} else if (index > 0) {
|
||||
writer.write(comma);
|
||||
}
|
||||
|
||||
state[1] = encodeInteger(writer, range[1], state[1]);
|
||||
|
||||
const fields =
|
||||
(range.length === 6 ? 0b0001 : 0) | (callsite ? 0b0010 : 0) | (isScope ? 0b0100 : 0);
|
||||
encodeInteger(writer, fields, 0);
|
||||
|
||||
if (range.length === 6) {
|
||||
const { 4: sourcesIndex, 5: scopesIndex } = range;
|
||||
if (sourcesIndex !== state[2]) {
|
||||
state[3] = 0;
|
||||
}
|
||||
state[2] = encodeInteger(writer, sourcesIndex, state[2]);
|
||||
state[3] = encodeInteger(writer, scopesIndex, state[3]);
|
||||
}
|
||||
|
||||
if (callsite) {
|
||||
const { 0: sourcesIndex, 1: callLine, 2: callColumn } = range.callsite!;
|
||||
if (sourcesIndex !== state[4]) {
|
||||
state[5] = 0;
|
||||
state[6] = 0;
|
||||
} else if (callLine !== state[5]) {
|
||||
state[6] = 0;
|
||||
}
|
||||
state[4] = encodeInteger(writer, sourcesIndex, state[4]);
|
||||
state[5] = encodeInteger(writer, callLine, state[5]);
|
||||
state[6] = encodeInteger(writer, callColumn, state[6]);
|
||||
}
|
||||
|
||||
if (bindings) {
|
||||
for (const binding of bindings) {
|
||||
if (binding.length > 1) encodeInteger(writer, -binding.length, 0);
|
||||
const expression = binding[0][0];
|
||||
encodeInteger(writer, expression, 0);
|
||||
let bindingStartLine = startLine;
|
||||
let bindingStartColumn = startColumn;
|
||||
for (let i = 1; i < binding.length; i++) {
|
||||
const expRange = binding[i];
|
||||
bindingStartLine = encodeInteger(writer, expRange[1]!, bindingStartLine);
|
||||
bindingStartColumn = encodeInteger(writer, expRange[2]!, bindingStartColumn);
|
||||
encodeInteger(writer, expRange[0]!, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (index++; index < ranges.length; ) {
|
||||
const next = ranges[index];
|
||||
const { 0: l, 1: c } = next;
|
||||
if (l > endLine || (l === endLine && c >= endColumn)) {
|
||||
break;
|
||||
}
|
||||
index = _encodeGeneratedRanges(ranges, index, writer, state);
|
||||
}
|
||||
|
||||
if (state[0] < endLine) {
|
||||
catchupLine(writer, state[0], endLine);
|
||||
state[0] = endLine;
|
||||
state[1] = 0;
|
||||
} else {
|
||||
writer.write(comma);
|
||||
}
|
||||
state[1] = encodeInteger(writer, endColumn, state[1]);
|
||||
|
||||
return index;
|
||||
}
|
||||
|
||||
function catchupLine(writer: StringWriter, lastLine: number, line: number) {
|
||||
do {
|
||||
writer.write(semicolon);
|
||||
} while (++lastLine < line);
|
||||
}
|
||||
111
backend/node_modules/@jridgewell/sourcemap-codec/src/sourcemap-codec.ts
generated
vendored
Normal file
111
backend/node_modules/@jridgewell/sourcemap-codec/src/sourcemap-codec.ts
generated
vendored
Normal file
@ -0,0 +1,111 @@
|
||||
import { comma, decodeInteger, encodeInteger, hasMoreVlq, semicolon } from './vlq';
|
||||
import { StringWriter, StringReader } from './strings';
|
||||
|
||||
export {
|
||||
decodeOriginalScopes,
|
||||
encodeOriginalScopes,
|
||||
decodeGeneratedRanges,
|
||||
encodeGeneratedRanges,
|
||||
} from './scopes';
|
||||
export type { OriginalScope, GeneratedRange, CallSite, BindingExpressionRange } from './scopes';
|
||||
|
||||
export type SourceMapSegment =
|
||||
| [number]
|
||||
| [number, number, number, number]
|
||||
| [number, number, number, number, number];
|
||||
export type SourceMapLine = SourceMapSegment[];
|
||||
export type SourceMapMappings = SourceMapLine[];
|
||||
|
||||
export function decode(mappings: string): SourceMapMappings {
|
||||
const { length } = mappings;
|
||||
const reader = new StringReader(mappings);
|
||||
const decoded: SourceMapMappings = [];
|
||||
let genColumn = 0;
|
||||
let sourcesIndex = 0;
|
||||
let sourceLine = 0;
|
||||
let sourceColumn = 0;
|
||||
let namesIndex = 0;
|
||||
|
||||
do {
|
||||
const semi = reader.indexOf(';');
|
||||
const line: SourceMapLine = [];
|
||||
let sorted = true;
|
||||
let lastCol = 0;
|
||||
genColumn = 0;
|
||||
|
||||
while (reader.pos < semi) {
|
||||
let seg: SourceMapSegment;
|
||||
|
||||
genColumn = decodeInteger(reader, genColumn);
|
||||
if (genColumn < lastCol) sorted = false;
|
||||
lastCol = genColumn;
|
||||
|
||||
if (hasMoreVlq(reader, semi)) {
|
||||
sourcesIndex = decodeInteger(reader, sourcesIndex);
|
||||
sourceLine = decodeInteger(reader, sourceLine);
|
||||
sourceColumn = decodeInteger(reader, sourceColumn);
|
||||
|
||||
if (hasMoreVlq(reader, semi)) {
|
||||
namesIndex = decodeInteger(reader, namesIndex);
|
||||
seg = [genColumn, sourcesIndex, sourceLine, sourceColumn, namesIndex];
|
||||
} else {
|
||||
seg = [genColumn, sourcesIndex, sourceLine, sourceColumn];
|
||||
}
|
||||
} else {
|
||||
seg = [genColumn];
|
||||
}
|
||||
|
||||
line.push(seg);
|
||||
reader.pos++;
|
||||
}
|
||||
|
||||
if (!sorted) sort(line);
|
||||
decoded.push(line);
|
||||
reader.pos = semi + 1;
|
||||
} while (reader.pos <= length);
|
||||
|
||||
return decoded;
|
||||
}
|
||||
|
||||
function sort(line: SourceMapSegment[]) {
|
||||
line.sort(sortComparator);
|
||||
}
|
||||
|
||||
function sortComparator(a: SourceMapSegment, b: SourceMapSegment): number {
|
||||
return a[0] - b[0];
|
||||
}
|
||||
|
||||
export function encode(decoded: SourceMapMappings): string;
|
||||
export function encode(decoded: Readonly<SourceMapMappings>): string;
|
||||
export function encode(decoded: Readonly<SourceMapMappings>): string {
|
||||
const writer = new StringWriter();
|
||||
let sourcesIndex = 0;
|
||||
let sourceLine = 0;
|
||||
let sourceColumn = 0;
|
||||
let namesIndex = 0;
|
||||
|
||||
for (let i = 0; i < decoded.length; i++) {
|
||||
const line = decoded[i];
|
||||
if (i > 0) writer.write(semicolon);
|
||||
if (line.length === 0) continue;
|
||||
|
||||
let genColumn = 0;
|
||||
|
||||
for (let j = 0; j < line.length; j++) {
|
||||
const segment = line[j];
|
||||
if (j > 0) writer.write(comma);
|
||||
|
||||
genColumn = encodeInteger(writer, segment[0], genColumn);
|
||||
|
||||
if (segment.length === 1) continue;
|
||||
sourcesIndex = encodeInteger(writer, segment[1], sourcesIndex);
|
||||
sourceLine = encodeInteger(writer, segment[2], sourceLine);
|
||||
sourceColumn = encodeInteger(writer, segment[3], sourceColumn);
|
||||
|
||||
if (segment.length === 4) continue;
|
||||
namesIndex = encodeInteger(writer, segment[4], namesIndex);
|
||||
}
|
||||
}
|
||||
|
||||
return writer.flush();
|
||||
}
|
||||
65
backend/node_modules/@jridgewell/sourcemap-codec/src/strings.ts
generated
vendored
Normal file
65
backend/node_modules/@jridgewell/sourcemap-codec/src/strings.ts
generated
vendored
Normal file
@ -0,0 +1,65 @@
|
||||
const bufLength = 1024 * 16;
|
||||
|
||||
// Provide a fallback for older environments.
|
||||
const td =
|
||||
typeof TextDecoder !== 'undefined'
|
||||
? /* #__PURE__ */ new TextDecoder()
|
||||
: typeof Buffer !== 'undefined'
|
||||
? {
|
||||
decode(buf: Uint8Array): string {
|
||||
const out = Buffer.from(buf.buffer, buf.byteOffset, buf.byteLength);
|
||||
return out.toString();
|
||||
},
|
||||
}
|
||||
: {
|
||||
decode(buf: Uint8Array): string {
|
||||
let out = '';
|
||||
for (let i = 0; i < buf.length; i++) {
|
||||
out += String.fromCharCode(buf[i]);
|
||||
}
|
||||
return out;
|
||||
},
|
||||
};
|
||||
|
||||
export class StringWriter {
|
||||
pos = 0;
|
||||
private out = '';
|
||||
private buffer = new Uint8Array(bufLength);
|
||||
|
||||
write(v: number): void {
|
||||
const { buffer } = this;
|
||||
buffer[this.pos++] = v;
|
||||
if (this.pos === bufLength) {
|
||||
this.out += td.decode(buffer);
|
||||
this.pos = 0;
|
||||
}
|
||||
}
|
||||
|
||||
flush(): string {
|
||||
const { buffer, out, pos } = this;
|
||||
return pos > 0 ? out + td.decode(buffer.subarray(0, pos)) : out;
|
||||
}
|
||||
}
|
||||
|
||||
export class StringReader {
|
||||
pos = 0;
|
||||
declare private buffer: string;
|
||||
|
||||
constructor(buffer: string) {
|
||||
this.buffer = buffer;
|
||||
}
|
||||
|
||||
next(): number {
|
||||
return this.buffer.charCodeAt(this.pos++);
|
||||
}
|
||||
|
||||
peek(): number {
|
||||
return this.buffer.charCodeAt(this.pos);
|
||||
}
|
||||
|
||||
indexOf(char: string): number {
|
||||
const { buffer, pos } = this;
|
||||
const idx = buffer.indexOf(char, pos);
|
||||
return idx === -1 ? buffer.length : idx;
|
||||
}
|
||||
}
|
||||
55
backend/node_modules/@jridgewell/sourcemap-codec/src/vlq.ts
generated
vendored
Normal file
55
backend/node_modules/@jridgewell/sourcemap-codec/src/vlq.ts
generated
vendored
Normal file
@ -0,0 +1,55 @@
|
||||
import type { StringReader, StringWriter } from './strings';
|
||||
|
||||
export const comma = ','.charCodeAt(0);
|
||||
export const semicolon = ';'.charCodeAt(0);
|
||||
|
||||
const chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/';
|
||||
const intToChar = new Uint8Array(64); // 64 possible chars.
|
||||
const charToInt = new Uint8Array(128); // z is 122 in ASCII
|
||||
|
||||
for (let i = 0; i < chars.length; i++) {
|
||||
const c = chars.charCodeAt(i);
|
||||
intToChar[i] = c;
|
||||
charToInt[c] = i;
|
||||
}
|
||||
|
||||
export function decodeInteger(reader: StringReader, relative: number): number {
|
||||
let value = 0;
|
||||
let shift = 0;
|
||||
let integer = 0;
|
||||
|
||||
do {
|
||||
const c = reader.next();
|
||||
integer = charToInt[c];
|
||||
value |= (integer & 31) << shift;
|
||||
shift += 5;
|
||||
} while (integer & 32);
|
||||
|
||||
const shouldNegate = value & 1;
|
||||
value >>>= 1;
|
||||
|
||||
if (shouldNegate) {
|
||||
value = -0x80000000 | -value;
|
||||
}
|
||||
|
||||
return relative + value;
|
||||
}
|
||||
|
||||
export function encodeInteger(builder: StringWriter, num: number, relative: number): number {
|
||||
let delta = num - relative;
|
||||
|
||||
delta = delta < 0 ? (-delta << 1) | 1 : delta << 1;
|
||||
do {
|
||||
let clamped = delta & 0b011111;
|
||||
delta >>>= 5;
|
||||
if (delta > 0) clamped |= 0b100000;
|
||||
builder.write(intToChar[clamped]);
|
||||
} while (delta > 0);
|
||||
|
||||
return num;
|
||||
}
|
||||
|
||||
export function hasMoreVlq(reader: StringReader, max: number) {
|
||||
if (reader.pos >= max) return false;
|
||||
return reader.peek() !== comma;
|
||||
}
|
||||
50
backend/node_modules/@jridgewell/sourcemap-codec/types/scopes.d.cts
generated
vendored
Normal file
50
backend/node_modules/@jridgewell/sourcemap-codec/types/scopes.d.cts
generated
vendored
Normal file
@ -0,0 +1,50 @@
|
||||
type Line = number;
|
||||
type Column = number;
|
||||
type Kind = number;
|
||||
type Name = number;
|
||||
type Var = number;
|
||||
type SourcesIndex = number;
|
||||
type ScopesIndex = number;
|
||||
type Mix<A, B, O> = (A & O) | (B & O);
|
||||
export type OriginalScope = Mix<[
|
||||
Line,
|
||||
Column,
|
||||
Line,
|
||||
Column,
|
||||
Kind
|
||||
], [
|
||||
Line,
|
||||
Column,
|
||||
Line,
|
||||
Column,
|
||||
Kind,
|
||||
Name
|
||||
], {
|
||||
vars: Var[];
|
||||
}>;
|
||||
export type GeneratedRange = Mix<[
|
||||
Line,
|
||||
Column,
|
||||
Line,
|
||||
Column
|
||||
], [
|
||||
Line,
|
||||
Column,
|
||||
Line,
|
||||
Column,
|
||||
SourcesIndex,
|
||||
ScopesIndex
|
||||
], {
|
||||
callsite: CallSite | null;
|
||||
bindings: Binding[];
|
||||
isScope: boolean;
|
||||
}>;
|
||||
export type CallSite = [SourcesIndex, Line, Column];
|
||||
type Binding = BindingExpressionRange[];
|
||||
export type BindingExpressionRange = [Name] | [Name, Line, Column];
|
||||
export declare function decodeOriginalScopes(input: string): OriginalScope[];
|
||||
export declare function encodeOriginalScopes(scopes: OriginalScope[]): string;
|
||||
export declare function decodeGeneratedRanges(input: string): GeneratedRange[];
|
||||
export declare function encodeGeneratedRanges(ranges: GeneratedRange[]): string;
|
||||
export {};
|
||||
//# sourceMappingURL=scopes.d.ts.map
|
||||
1
backend/node_modules/@jridgewell/sourcemap-codec/types/scopes.d.cts.map
generated
vendored
Normal file
1
backend/node_modules/@jridgewell/sourcemap-codec/types/scopes.d.cts.map
generated
vendored
Normal file
@ -0,0 +1 @@
|
||||
{"version":3,"file":"scopes.d.ts","sourceRoot":"","sources":["../src/scopes.ts"],"names":[],"mappings":"AAKA,KAAK,IAAI,GAAG,MAAM,CAAC;AACnB,KAAK,MAAM,GAAG,MAAM,CAAC;AACrB,KAAK,IAAI,GAAG,MAAM,CAAC;AACnB,KAAK,IAAI,GAAG,MAAM,CAAC;AACnB,KAAK,GAAG,GAAG,MAAM,CAAC;AAClB,KAAK,YAAY,GAAG,MAAM,CAAC;AAC3B,KAAK,WAAW,GAAG,MAAM,CAAC;AAE1B,KAAK,GAAG,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;AAEtC,MAAM,MAAM,aAAa,GAAG,GAAG,CAC7B;IAAC,IAAI;IAAE,MAAM;IAAE,IAAI;IAAE,MAAM;IAAE,IAAI;CAAC,EAClC;IAAC,IAAI;IAAE,MAAM;IAAE,IAAI;IAAE,MAAM;IAAE,IAAI;IAAE,IAAI;CAAC,EACxC;IAAE,IAAI,EAAE,GAAG,EAAE,CAAA;CAAE,CAChB,CAAC;AAEF,MAAM,MAAM,cAAc,GAAG,GAAG,CAC9B;IAAC,IAAI;IAAE,MAAM;IAAE,IAAI;IAAE,MAAM;CAAC,EAC5B;IAAC,IAAI;IAAE,MAAM;IAAE,IAAI;IAAE,MAAM;IAAE,YAAY;IAAE,WAAW;CAAC,EACvD;IACE,QAAQ,EAAE,QAAQ,GAAG,IAAI,CAAC;IAC1B,QAAQ,EAAE,OAAO,EAAE,CAAC;IACpB,OAAO,EAAE,OAAO,CAAC;CAClB,CACF,CAAC;AACF,MAAM,MAAM,QAAQ,GAAG,CAAC,YAAY,EAAE,IAAI,EAAE,MAAM,CAAC,CAAC;AACpD,KAAK,OAAO,GAAG,sBAAsB,EAAE,CAAC;AACxC,MAAM,MAAM,sBAAsB,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,EAAE,IAAI,EAAE,MAAM,CAAC,CAAC;AAEnE,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,MAAM,GAAG,aAAa,EAAE,CAyCnE;AAED,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,aAAa,EAAE,GAAG,MAAM,CAQpE;AA2CD,wBAAgB,qBAAqB,CAAC,KAAK,EAAE,MAAM,GAAG,cAAc,EAAE,CAoGrE;AAED,wBAAgB,qBAAqB,CAAC,MAAM,EAAE,cAAc,EAAE,GAAG,MAAM,CAUtE"}
|
||||
50
backend/node_modules/@jridgewell/sourcemap-codec/types/scopes.d.mts
generated
vendored
Normal file
50
backend/node_modules/@jridgewell/sourcemap-codec/types/scopes.d.mts
generated
vendored
Normal file
@ -0,0 +1,50 @@
|
||||
type Line = number;
|
||||
type Column = number;
|
||||
type Kind = number;
|
||||
type Name = number;
|
||||
type Var = number;
|
||||
type SourcesIndex = number;
|
||||
type ScopesIndex = number;
|
||||
type Mix<A, B, O> = (A & O) | (B & O);
|
||||
export type OriginalScope = Mix<[
|
||||
Line,
|
||||
Column,
|
||||
Line,
|
||||
Column,
|
||||
Kind
|
||||
], [
|
||||
Line,
|
||||
Column,
|
||||
Line,
|
||||
Column,
|
||||
Kind,
|
||||
Name
|
||||
], {
|
||||
vars: Var[];
|
||||
}>;
|
||||
export type GeneratedRange = Mix<[
|
||||
Line,
|
||||
Column,
|
||||
Line,
|
||||
Column
|
||||
], [
|
||||
Line,
|
||||
Column,
|
||||
Line,
|
||||
Column,
|
||||
SourcesIndex,
|
||||
ScopesIndex
|
||||
], {
|
||||
callsite: CallSite | null;
|
||||
bindings: Binding[];
|
||||
isScope: boolean;
|
||||
}>;
|
||||
export type CallSite = [SourcesIndex, Line, Column];
|
||||
type Binding = BindingExpressionRange[];
|
||||
export type BindingExpressionRange = [Name] | [Name, Line, Column];
|
||||
export declare function decodeOriginalScopes(input: string): OriginalScope[];
|
||||
export declare function encodeOriginalScopes(scopes: OriginalScope[]): string;
|
||||
export declare function decodeGeneratedRanges(input: string): GeneratedRange[];
|
||||
export declare function encodeGeneratedRanges(ranges: GeneratedRange[]): string;
|
||||
export {};
|
||||
//# sourceMappingURL=scopes.d.ts.map
|
||||
1
backend/node_modules/@jridgewell/sourcemap-codec/types/scopes.d.mts.map
generated
vendored
Normal file
1
backend/node_modules/@jridgewell/sourcemap-codec/types/scopes.d.mts.map
generated
vendored
Normal file
@ -0,0 +1 @@
|
||||
{"version":3,"file":"scopes.d.ts","sourceRoot":"","sources":["../src/scopes.ts"],"names":[],"mappings":"AAKA,KAAK,IAAI,GAAG,MAAM,CAAC;AACnB,KAAK,MAAM,GAAG,MAAM,CAAC;AACrB,KAAK,IAAI,GAAG,MAAM,CAAC;AACnB,KAAK,IAAI,GAAG,MAAM,CAAC;AACnB,KAAK,GAAG,GAAG,MAAM,CAAC;AAClB,KAAK,YAAY,GAAG,MAAM,CAAC;AAC3B,KAAK,WAAW,GAAG,MAAM,CAAC;AAE1B,KAAK,GAAG,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;AAEtC,MAAM,MAAM,aAAa,GAAG,GAAG,CAC7B;IAAC,IAAI;IAAE,MAAM;IAAE,IAAI;IAAE,MAAM;IAAE,IAAI;CAAC,EAClC;IAAC,IAAI;IAAE,MAAM;IAAE,IAAI;IAAE,MAAM;IAAE,IAAI;IAAE,IAAI;CAAC,EACxC;IAAE,IAAI,EAAE,GAAG,EAAE,CAAA;CAAE,CAChB,CAAC;AAEF,MAAM,MAAM,cAAc,GAAG,GAAG,CAC9B;IAAC,IAAI;IAAE,MAAM;IAAE,IAAI;IAAE,MAAM;CAAC,EAC5B;IAAC,IAAI;IAAE,MAAM;IAAE,IAAI;IAAE,MAAM;IAAE,YAAY;IAAE,WAAW;CAAC,EACvD;IACE,QAAQ,EAAE,QAAQ,GAAG,IAAI,CAAC;IAC1B,QAAQ,EAAE,OAAO,EAAE,CAAC;IACpB,OAAO,EAAE,OAAO,CAAC;CAClB,CACF,CAAC;AACF,MAAM,MAAM,QAAQ,GAAG,CAAC,YAAY,EAAE,IAAI,EAAE,MAAM,CAAC,CAAC;AACpD,KAAK,OAAO,GAAG,sBAAsB,EAAE,CAAC;AACxC,MAAM,MAAM,sBAAsB,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,EAAE,IAAI,EAAE,MAAM,CAAC,CAAC;AAEnE,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,MAAM,GAAG,aAAa,EAAE,CAyCnE;AAED,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,aAAa,EAAE,GAAG,MAAM,CAQpE;AA2CD,wBAAgB,qBAAqB,CAAC,KAAK,EAAE,MAAM,GAAG,cAAc,EAAE,CAoGrE;AAED,wBAAgB,qBAAqB,CAAC,MAAM,EAAE,cAAc,EAAE,GAAG,MAAM,CAUtE"}
|
||||
9
backend/node_modules/@jridgewell/sourcemap-codec/types/sourcemap-codec.d.cts
generated
vendored
Normal file
9
backend/node_modules/@jridgewell/sourcemap-codec/types/sourcemap-codec.d.cts
generated
vendored
Normal file
@ -0,0 +1,9 @@
|
||||
export { decodeOriginalScopes, encodeOriginalScopes, decodeGeneratedRanges, encodeGeneratedRanges, } from './scopes.cts';
|
||||
export type { OriginalScope, GeneratedRange, CallSite, BindingExpressionRange } from './scopes.cts';
|
||||
export type SourceMapSegment = [number] | [number, number, number, number] | [number, number, number, number, number];
|
||||
export type SourceMapLine = SourceMapSegment[];
|
||||
export type SourceMapMappings = SourceMapLine[];
|
||||
export declare function decode(mappings: string): SourceMapMappings;
|
||||
export declare function encode(decoded: SourceMapMappings): string;
|
||||
export declare function encode(decoded: Readonly<SourceMapMappings>): string;
|
||||
//# sourceMappingURL=sourcemap-codec.d.ts.map
|
||||
1
backend/node_modules/@jridgewell/sourcemap-codec/types/sourcemap-codec.d.cts.map
generated
vendored
Normal file
1
backend/node_modules/@jridgewell/sourcemap-codec/types/sourcemap-codec.d.cts.map
generated
vendored
Normal file
@ -0,0 +1 @@
|
||||
{"version":3,"file":"sourcemap-codec.d.ts","sourceRoot":"","sources":["../src/sourcemap-codec.ts"],"names":[],"mappings":"AAGA,OAAO,EACL,oBAAoB,EACpB,oBAAoB,EACpB,qBAAqB,EACrB,qBAAqB,GACtB,MAAM,UAAU,CAAC;AAClB,YAAY,EAAE,aAAa,EAAE,cAAc,EAAE,QAAQ,EAAE,sBAAsB,EAAE,MAAM,UAAU,CAAC;AAEhG,MAAM,MAAM,gBAAgB,GACxB,CAAC,MAAM,CAAC,GACR,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,GAChC,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC;AAC7C,MAAM,MAAM,aAAa,GAAG,gBAAgB,EAAE,CAAC;AAC/C,MAAM,MAAM,iBAAiB,GAAG,aAAa,EAAE,CAAC;AAEhD,wBAAgB,MAAM,CAAC,QAAQ,EAAE,MAAM,GAAG,iBAAiB,CAiD1D;AAUD,wBAAgB,MAAM,CAAC,OAAO,EAAE,iBAAiB,GAAG,MAAM,CAAC;AAC3D,wBAAgB,MAAM,CAAC,OAAO,EAAE,QAAQ,CAAC,iBAAiB,CAAC,GAAG,MAAM,CAAC"}
|
||||
9
backend/node_modules/@jridgewell/sourcemap-codec/types/sourcemap-codec.d.mts
generated
vendored
Normal file
9
backend/node_modules/@jridgewell/sourcemap-codec/types/sourcemap-codec.d.mts
generated
vendored
Normal file
@ -0,0 +1,9 @@
|
||||
export { decodeOriginalScopes, encodeOriginalScopes, decodeGeneratedRanges, encodeGeneratedRanges, } from './scopes.mts';
|
||||
export type { OriginalScope, GeneratedRange, CallSite, BindingExpressionRange } from './scopes.mts';
|
||||
export type SourceMapSegment = [number] | [number, number, number, number] | [number, number, number, number, number];
|
||||
export type SourceMapLine = SourceMapSegment[];
|
||||
export type SourceMapMappings = SourceMapLine[];
|
||||
export declare function decode(mappings: string): SourceMapMappings;
|
||||
export declare function encode(decoded: SourceMapMappings): string;
|
||||
export declare function encode(decoded: Readonly<SourceMapMappings>): string;
|
||||
//# sourceMappingURL=sourcemap-codec.d.ts.map
|
||||
1
backend/node_modules/@jridgewell/sourcemap-codec/types/sourcemap-codec.d.mts.map
generated
vendored
Normal file
1
backend/node_modules/@jridgewell/sourcemap-codec/types/sourcemap-codec.d.mts.map
generated
vendored
Normal file
@ -0,0 +1 @@
|
||||
{"version":3,"file":"sourcemap-codec.d.ts","sourceRoot":"","sources":["../src/sourcemap-codec.ts"],"names":[],"mappings":"AAGA,OAAO,EACL,oBAAoB,EACpB,oBAAoB,EACpB,qBAAqB,EACrB,qBAAqB,GACtB,MAAM,UAAU,CAAC;AAClB,YAAY,EAAE,aAAa,EAAE,cAAc,EAAE,QAAQ,EAAE,sBAAsB,EAAE,MAAM,UAAU,CAAC;AAEhG,MAAM,MAAM,gBAAgB,GACxB,CAAC,MAAM,CAAC,GACR,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,GAChC,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC;AAC7C,MAAM,MAAM,aAAa,GAAG,gBAAgB,EAAE,CAAC;AAC/C,MAAM,MAAM,iBAAiB,GAAG,aAAa,EAAE,CAAC;AAEhD,wBAAgB,MAAM,CAAC,QAAQ,EAAE,MAAM,GAAG,iBAAiB,CAiD1D;AAUD,wBAAgB,MAAM,CAAC,OAAO,EAAE,iBAAiB,GAAG,MAAM,CAAC;AAC3D,wBAAgB,MAAM,CAAC,OAAO,EAAE,QAAQ,CAAC,iBAAiB,CAAC,GAAG,MAAM,CAAC"}
|
||||
16
backend/node_modules/@jridgewell/sourcemap-codec/types/strings.d.cts
generated
vendored
Normal file
16
backend/node_modules/@jridgewell/sourcemap-codec/types/strings.d.cts
generated
vendored
Normal file
@ -0,0 +1,16 @@
|
||||
export declare class StringWriter {
|
||||
pos: number;
|
||||
private out;
|
||||
private buffer;
|
||||
write(v: number): void;
|
||||
flush(): string;
|
||||
}
|
||||
export declare class StringReader {
|
||||
pos: number;
|
||||
private buffer;
|
||||
constructor(buffer: string);
|
||||
next(): number;
|
||||
peek(): number;
|
||||
indexOf(char: string): number;
|
||||
}
|
||||
//# sourceMappingURL=strings.d.ts.map
|
||||
1
backend/node_modules/@jridgewell/sourcemap-codec/types/strings.d.cts.map
generated
vendored
Normal file
1
backend/node_modules/@jridgewell/sourcemap-codec/types/strings.d.cts.map
generated
vendored
Normal file
@ -0,0 +1 @@
|
||||
{"version":3,"file":"strings.d.ts","sourceRoot":"","sources":["../src/strings.ts"],"names":[],"mappings":"AAuBA,qBAAa,YAAY;IACvB,GAAG,SAAK;IACR,OAAO,CAAC,GAAG,CAAM;IACjB,OAAO,CAAC,MAAM,CAA6B;IAE3C,KAAK,CAAC,CAAC,EAAE,MAAM,GAAG,IAAI;IAStB,KAAK,IAAI,MAAM;CAIhB;AAED,qBAAa,YAAY;IACvB,GAAG,SAAK;IACR,QAAgB,MAAM,CAAS;gBAEnB,MAAM,EAAE,MAAM;IAI1B,IAAI,IAAI,MAAM;IAId,IAAI,IAAI,MAAM;IAId,OAAO,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM;CAK9B"}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user