Initial commit: CHORUS PING! blog
- Next.js 14 blog application with theme support - Docker containerization with volume bindings - Traefik integration with Let's Encrypt SSL - MDX support for blog posts - Theme toggle with localStorage persistence - Scheduled posts directory structure - Brand guidelines compliance with CHORUS colors 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
44
.dockerignore
Normal file
@@ -0,0 +1,44 @@
|
||||
# Build and development files
|
||||
Dockerfile
|
||||
.dockerignore
|
||||
node_modules
|
||||
npm-debug.log
|
||||
.next
|
||||
.nyc_output
|
||||
coverage
|
||||
|
||||
# Environment and config files
|
||||
.env*
|
||||
.git
|
||||
.gitignore
|
||||
.vscode
|
||||
.eslintrc.json
|
||||
next.config.js.bak
|
||||
|
||||
# Documentation
|
||||
README.md
|
||||
docs/
|
||||
|
||||
# Docker compose files (for development)
|
||||
docker-compose*.yml
|
||||
|
||||
# Development scripts
|
||||
dev-start.sh
|
||||
|
||||
# Log files
|
||||
*.log
|
||||
logs/
|
||||
|
||||
# OS generated files
|
||||
.DS_Store
|
||||
.DS_Store?
|
||||
._*
|
||||
.Spotlight-V100
|
||||
.Trashes
|
||||
ehthumbs.db
|
||||
Thumbs.db
|
||||
|
||||
# Keep posts and scheduled directories for volume mounting
|
||||
# (they'll be mounted as volumes anyway)
|
||||
posts/
|
||||
scheduled/
|
||||
51
.gitignore
vendored
Normal file
@@ -0,0 +1,51 @@
|
||||
# dependencies
|
||||
/node_modules
|
||||
/.pnp
|
||||
.pnp.js
|
||||
|
||||
# testing
|
||||
/coverage
|
||||
|
||||
# next.js
|
||||
/.next/
|
||||
/out/
|
||||
|
||||
# production
|
||||
/build
|
||||
|
||||
# misc
|
||||
.DS_Store
|
||||
*.pem
|
||||
|
||||
# debug
|
||||
npm-debug.log*
|
||||
yarn-debug.log*
|
||||
yarn-error.log*
|
||||
|
||||
# local env files
|
||||
.env*.local
|
||||
|
||||
# vercel
|
||||
.vercel
|
||||
|
||||
# typescript
|
||||
*.tsbuildinfo
|
||||
next-env.d.ts
|
||||
|
||||
# IDE files
|
||||
.vscode/
|
||||
.idea/
|
||||
|
||||
# Environment files
|
||||
.env
|
||||
.env.production
|
||||
|
||||
# Logs
|
||||
logs/
|
||||
*.log
|
||||
|
||||
# Cache
|
||||
.cache/
|
||||
|
||||
# Development scripts
|
||||
dev-start.sh.bak
|
||||
55
Dockerfile
Normal file
@@ -0,0 +1,55 @@
|
||||
# CHORUS Services - Blog
|
||||
# Static blog built with Next.js
|
||||
|
||||
FROM node:18-alpine AS base
|
||||
|
||||
# Install dependencies only when needed
|
||||
FROM base AS deps
|
||||
RUN apk add --no-cache libc6-compat
|
||||
WORKDIR /app
|
||||
|
||||
# Copy package files
|
||||
COPY package.json package-lock.json* ./
|
||||
RUN npm ci --only=production
|
||||
|
||||
# Rebuild the source code only when needed
|
||||
FROM base AS builder
|
||||
WORKDIR /app
|
||||
COPY --from=deps /app/node_modules ./node_modules
|
||||
COPY . .
|
||||
|
||||
# Set build-time environment variables
|
||||
ENV NEXT_TELEMETRY_DISABLED 1
|
||||
ENV NODE_ENV production
|
||||
|
||||
# Build the application
|
||||
RUN npm run build
|
||||
|
||||
# Production image, copy all the files and run next
|
||||
FROM base AS runner
|
||||
WORKDIR /app
|
||||
|
||||
ENV NODE_ENV production
|
||||
ENV NEXT_TELEMETRY_DISABLED 1
|
||||
|
||||
# Create non-root user
|
||||
RUN addgroup --system --gid 1001 nodejs
|
||||
RUN adduser --system --uid 1001 nextjs
|
||||
|
||||
# Copy built application
|
||||
COPY --from=builder /app/public ./public
|
||||
COPY --from=builder --chown=nextjs:nodejs /app/.next/standalone ./
|
||||
COPY --from=builder --chown=nextjs:nodejs /app/.next/static ./.next/static
|
||||
|
||||
# Create directories for mounted volumes
|
||||
RUN mkdir -p /app/posts /app/scheduled
|
||||
RUN chown -R nextjs:nodejs /app/posts /app/scheduled
|
||||
|
||||
USER nextjs
|
||||
|
||||
EXPOSE 3000
|
||||
|
||||
ENV PORT 3000
|
||||
ENV HOSTNAME "0.0.0.0"
|
||||
|
||||
CMD ["node", "server.js"]
|
||||
147
README.md
Normal file
@@ -0,0 +1,147 @@
|
||||
# CHORUS Blog
|
||||
|
||||
A static blog built with Next.js for sharing insights about contextual AI orchestration, agent coordination, and intelligent systems.
|
||||
|
||||
## Features
|
||||
|
||||
- **Static Blog Posts**: Markdown-based blog posts with MDX support
|
||||
- **CHORUS Brand Styling**: Consistent with the main CHORUS design system
|
||||
- **SEO Optimized**: Full metadata, OpenGraph, and Twitter Card support
|
||||
- **Responsive Design**: Mobile-first design that works on all devices
|
||||
- **Typography**: Clean, readable typography optimized for technical content
|
||||
- **Code Highlighting**: Syntax highlighting for code blocks
|
||||
- **Fast Performance**: Optimized build with static generation
|
||||
|
||||
## Development
|
||||
|
||||
### Quick Start
|
||||
|
||||
```bash
|
||||
# Start the development server
|
||||
./dev-start.sh
|
||||
|
||||
# Or manually
|
||||
npm install
|
||||
npm run dev
|
||||
```
|
||||
|
||||
The blog will be available at `http://localhost:3002`
|
||||
|
||||
### Adding Blog Posts
|
||||
|
||||
1. Create a new `.md` file in `content/posts/`
|
||||
2. Add frontmatter with metadata:
|
||||
|
||||
```yaml
|
||||
---
|
||||
title: "Your Post Title"
|
||||
description: "Brief description of the post"
|
||||
date: "2025-01-27"
|
||||
author:
|
||||
name: "Author Name"
|
||||
role: "Author Role"
|
||||
tags: ["tag1", "tag2", "tag3"]
|
||||
featured: false
|
||||
---
|
||||
```
|
||||
|
||||
3. Write your content in Markdown
|
||||
4. The post will automatically appear on the blog
|
||||
|
||||
### Project Structure
|
||||
|
||||
```
|
||||
├── app/ # Next.js app directory
|
||||
│ ├── posts/[slug]/ # Dynamic blog post pages
|
||||
│ ├── layout.tsx # Root layout
|
||||
│ └── page.tsx # Homepage
|
||||
├── components/ # React components
|
||||
│ ├── BlogHeader.tsx # Site header
|
||||
│ ├── BlogFooter.tsx # Site footer
|
||||
│ └── PostCard.tsx # Blog post card
|
||||
├── content/posts/ # Blog post markdown files
|
||||
├── lib/ # Utilities
|
||||
│ └── blog.ts # Blog post handling
|
||||
├── types/ # TypeScript types
|
||||
└── public/ # Static assets
|
||||
```
|
||||
|
||||
## Deployment
|
||||
|
||||
### Docker
|
||||
|
||||
```bash
|
||||
# Build the Docker image
|
||||
npm run docker:build
|
||||
|
||||
# Run with Docker Compose
|
||||
npm run docker:compose
|
||||
```
|
||||
|
||||
### Production Build
|
||||
|
||||
```bash
|
||||
npm run build
|
||||
npm start
|
||||
```
|
||||
|
||||
The blog uses Next.js's static generation features for optimal performance.
|
||||
|
||||
## Configuration
|
||||
|
||||
### Tailwind CSS
|
||||
|
||||
The blog uses the same Tailwind configuration as the main CHORUS website, ensuring brand consistency. The configuration includes:
|
||||
|
||||
- CHORUS color palette (carbon, mulberry, ocean, etc.)
|
||||
- Typography scale and font families
|
||||
- Custom spacing and sizing utilities
|
||||
- Blog-specific prose styling
|
||||
|
||||
### Environment Variables
|
||||
|
||||
No environment variables are required for basic operation. The blog is designed to work as a static site.
|
||||
|
||||
## Brand Guidelines
|
||||
|
||||
The blog follows the CHORUS brand guidelines:
|
||||
|
||||
- **Colors**: Carbon (grays), Mulberry (purples), Ocean (blues)
|
||||
- **Typography**: Inter Tight for body text, Exo for headings
|
||||
- **Logo**: Consistent CHORUS branding
|
||||
- **Spacing**: Golden ratio-based spacing system
|
||||
|
||||
## Adding New Features
|
||||
|
||||
### New Page Types
|
||||
|
||||
Create new pages in the `app/` directory following Next.js 13+ app router conventions.
|
||||
|
||||
### Custom Components
|
||||
|
||||
Add new components to the `components/` directory. All components should:
|
||||
|
||||
- Use TypeScript
|
||||
- Follow the existing naming conventions
|
||||
- Be responsive by default
|
||||
- Use CHORUS brand colors and typography
|
||||
|
||||
### Styling
|
||||
|
||||
- Use Tailwind CSS classes
|
||||
- Reference the existing design tokens
|
||||
- Maintain consistency with the CHORUS brand
|
||||
|
||||
## Production Deployment
|
||||
|
||||
The blog is configured for deployment with:
|
||||
|
||||
- **Docker**: Multi-stage build for production
|
||||
- **Traefik**: Reverse proxy with Let's Encrypt SSL
|
||||
- **Docker Swarm**: Container orchestration
|
||||
|
||||
Production URL: `https://blog.chorus.services`
|
||||
|
||||
## License
|
||||
|
||||
Proprietary - CHORUS Services
|
||||
116
app/globals.css
Normal file
@@ -0,0 +1,116 @@
|
||||
@import url('https://fonts.googleapis.com/css2?family=Inter+Tight:ital,wght@0,100..900;1,100..900&family=Exo:ital,wght@0,100..900;1,100..900&family=Inconsolata:wdth,wght@50..200,200..900&display=swap');
|
||||
@tailwind base;
|
||||
@tailwind components;
|
||||
@tailwind utilities;
|
||||
|
||||
:root {
|
||||
--font-inter: 'Inter Tight', ui-sans-serif, system-ui;
|
||||
--font-exo: 'Exo', 'Inter Tight', ui-sans-serif, system-ui;
|
||||
--font-mono: 'Inconsolata', ui-monospace, monospace;
|
||||
}
|
||||
|
||||
html {
|
||||
font-feature-settings: "cv02", "cv03", "cv04", "cv11";
|
||||
scroll-behavior: smooth;
|
||||
}
|
||||
|
||||
body {
|
||||
font-feature-settings: "cv02", "cv03", "cv04", "cv11";
|
||||
-webkit-font-smoothing: antialiased;
|
||||
-moz-osx-font-smoothing: grayscale;
|
||||
}
|
||||
|
||||
/* CHORUS Blog Typography */
|
||||
.prose {
|
||||
@apply max-w-none text-carbon-950 dark:text-carbon-100;
|
||||
}
|
||||
|
||||
.prose h1 {
|
||||
@apply text-h2 font-sans font-thin text-carbon-950 dark:text-mulberry-100 mb-8;
|
||||
}
|
||||
|
||||
.prose h2 {
|
||||
@apply text-h3 font-logo text-carbon-950 dark:text-mulberry-200 mb-6 mt-12;
|
||||
}
|
||||
|
||||
.prose h3 {
|
||||
@apply text-h4 font-sans text-carbon-950 dark:text-mulberry-300 mb-4 mt-8;
|
||||
}
|
||||
|
||||
.prose h4 {
|
||||
@apply text-h5 font-sans text-carbon-800 dark:text-mulberry-400 mb-3 mt-6;
|
||||
}
|
||||
|
||||
.prose h5 {
|
||||
@apply text-h6 font-sans text-carbon-700 dark:text-mulberry-500 mb-3 mt-6;
|
||||
}
|
||||
|
||||
.prose h6 {
|
||||
@apply text-h7 font-sans text-carbon-600 dark:text-mulberry-600 mb-2 mt-4;
|
||||
}
|
||||
|
||||
.prose p {
|
||||
@apply text-base leading-relaxed mb-6 text-carbon-800 dark:text-carbon-200;
|
||||
}
|
||||
|
||||
.prose a {
|
||||
@apply text-ocean-600 dark:text-ocean-400 hover:text-ocean-800 dark:hover:text-ocean-300 transition-colors underline decoration-ocean-500/30 hover:decoration-ocean-600/50 dark:hover:decoration-ocean-400/50;
|
||||
}
|
||||
|
||||
.prose strong {
|
||||
@apply text-carbon-950 dark:text-carbon-100 font-semibold;
|
||||
}
|
||||
|
||||
.prose code {
|
||||
@apply bg-carbon-200 dark:bg-carbon-800 text-eucalyptus-700 dark:text-eucalyptus-400 px-2 py-1 rounded-sm font-mono text-sm;
|
||||
}
|
||||
|
||||
.prose pre {
|
||||
@apply bg-carbon-100 dark:bg-carbon-900 border border-carbon-300 dark:border-carbon-700 rounded-lg overflow-x-auto p-4 mb-6;
|
||||
}
|
||||
|
||||
.prose pre code {
|
||||
@apply bg-transparent text-carbon-950 dark:text-carbon-200 p-0;
|
||||
}
|
||||
|
||||
.prose blockquote {
|
||||
@apply border-l-4 border-carbon-400 dark:border-mulberry-600 pl-6 italic text-carbon-600 dark:text-carbon-300 my-6;
|
||||
}
|
||||
|
||||
.prose ul {
|
||||
@apply list-disc pl-6 mb-6 space-y-2;
|
||||
}
|
||||
|
||||
.prose ol {
|
||||
@apply list-decimal pl-6 mb-6 space-y-2;
|
||||
}
|
||||
|
||||
.prose li {
|
||||
@apply text-carbon-800 dark:text-carbon-200;
|
||||
}
|
||||
|
||||
/* Blog-specific utilities */
|
||||
.blog-container {
|
||||
@apply max-w-4xl mx-auto px-4 sm:px-6 lg:px-8;
|
||||
}
|
||||
|
||||
.blog-meta {
|
||||
@apply text-sm text-carbon-600 dark:text-carbon-500 flex items-center space-x-4;
|
||||
}
|
||||
|
||||
.blog-tag {
|
||||
@apply inline-block bg-carbon-200 dark:bg-mulberry-800 text-carbon-700 dark:text-mulberry-200 px-3 py-1 rounded-full text-xs font-medium;
|
||||
}
|
||||
|
||||
/* Reading progress indicator */
|
||||
.reading-progress {
|
||||
@apply fixed top-0 left-0 w-full h-1 bg-ocean-600 dark:bg-mulberry-600 transform origin-left scale-x-0 transition-transform z-50;
|
||||
}
|
||||
|
||||
/* Utilities */
|
||||
.line-clamp-3 {
|
||||
overflow: hidden;
|
||||
display: -webkit-box;
|
||||
-webkit-box-orient: vertical;
|
||||
-webkit-line-clamp: 3;
|
||||
}
|
||||
113
app/layout.tsx
Normal file
@@ -0,0 +1,113 @@
|
||||
import type { Metadata } from 'next'
|
||||
import { Inter, Exo } from 'next/font/google'
|
||||
import './globals.css'
|
||||
|
||||
const inter = Inter({
|
||||
subsets: ['latin'],
|
||||
variable: '--font-inter',
|
||||
display: 'swap',
|
||||
})
|
||||
|
||||
const exo = Exo({
|
||||
subsets: ['latin'],
|
||||
variable: '--font-exo',
|
||||
display: 'swap',
|
||||
weight: ['100', '200', '300', '400', '500', '600', '700', '800', '900'],
|
||||
})
|
||||
|
||||
export const metadata: Metadata = {
|
||||
title: 'CHORUS PING! - Insights on Contextual AI',
|
||||
description: 'Deep dives into contextual AI orchestration, agent coordination, and the future of intelligent systems.',
|
||||
keywords: ['contextual AI', 'agent orchestration', 'enterprise AI', 'AI insights', 'technology blog'],
|
||||
authors: [{ name: 'Anthony Lewis Rawlins', url: 'https://deepblack.cloud' }],
|
||||
creator: 'Deep Black Cloud',
|
||||
publisher: 'CHORUS Services',
|
||||
metadataBase: new URL('https://blog.chorus.services'),
|
||||
alternates: {
|
||||
canonical: 'https://blog.chorus.services',
|
||||
},
|
||||
openGraph: {
|
||||
type: 'website',
|
||||
locale: 'en_US',
|
||||
url: 'https://blog.chorus.services',
|
||||
siteName: 'CHORUS PING!',
|
||||
title: 'CHORUS PING! - Insights on Contextual AI',
|
||||
description: 'Deep dives into contextual AI orchestration, agent coordination, and the future of intelligent systems.',
|
||||
images: [
|
||||
{
|
||||
url: '/logos/logo-ring-only.png',
|
||||
width: 256,
|
||||
height: 256,
|
||||
alt: 'CHORUS Services Logo',
|
||||
},
|
||||
],
|
||||
},
|
||||
twitter: {
|
||||
card: 'summary_large_image',
|
||||
title: 'CHORUS PING! - Insights on Contextual AI',
|
||||
description: 'Deep dives into contextual AI orchestration, agent coordination, and the future of intelligent systems.',
|
||||
images: ['/logos/chorus-landscape-on-blue.png'],
|
||||
},
|
||||
robots: {
|
||||
index: true,
|
||||
follow: true,
|
||||
googleBot: {
|
||||
index: true,
|
||||
follow: true,
|
||||
'max-video-preview': -1,
|
||||
'max-image-preview': 'large',
|
||||
'max-snippet': -1,
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
export default function RootLayout({
|
||||
children,
|
||||
}: {
|
||||
children: React.ReactNode
|
||||
}) {
|
||||
return (
|
||||
<html lang="en">
|
||||
<head>
|
||||
{/* Google tag (gtag.js) */}
|
||||
<script async src="https://www.googletagmanager.com/gtag/js?id=G-WTFF8JL9SF"></script>
|
||||
<script
|
||||
dangerouslySetInnerHTML={{
|
||||
__html: `
|
||||
window.dataLayer = window.dataLayer || [];
|
||||
function gtag(){dataLayer.push(arguments);}
|
||||
gtag('js', new Date());
|
||||
gtag('config', 'G-WTFF8JL9SF');
|
||||
`,
|
||||
}}
|
||||
/>
|
||||
{/* Theme initialization script */}
|
||||
<script
|
||||
dangerouslySetInnerHTML={{
|
||||
__html: `
|
||||
(function() {
|
||||
try {
|
||||
var theme = localStorage.getItem('theme');
|
||||
var prefersDark = window.matchMedia('(prefers-color-scheme: dark)').matches;
|
||||
var shouldBeDark = theme === 'dark' || (!theme && prefersDark);
|
||||
|
||||
if (shouldBeDark) {
|
||||
document.documentElement.classList.add('dark');
|
||||
} else {
|
||||
document.documentElement.classList.remove('dark');
|
||||
}
|
||||
} catch (e) {
|
||||
// If localStorage is not available, default to dark
|
||||
document.documentElement.classList.add('dark');
|
||||
}
|
||||
})();
|
||||
`,
|
||||
}}
|
||||
/>
|
||||
</head>
|
||||
<body className={`${inter.variable} ${exo.variable} font-sans bg-white dark:bg-carbon-950 text-carbon-950 dark:text-carbon-100 transition-colors duration-300`}>
|
||||
{children}
|
||||
</body>
|
||||
</html>
|
||||
)
|
||||
}
|
||||
68
app/page.tsx
Normal file
@@ -0,0 +1,68 @@
|
||||
import { getSortedPostsData, getFeaturedPosts } from '@/lib/blog'
|
||||
import BlogHeader from '@/components/BlogHeader'
|
||||
import BlogFooter from '@/components/BlogFooter'
|
||||
import PostCard from '@/components/PostCard'
|
||||
|
||||
export default function HomePage() {
|
||||
const allPosts = getSortedPostsData()
|
||||
const featuredPosts = getFeaturedPosts()
|
||||
const recentPosts = allPosts.slice(0, 6)
|
||||
|
||||
return (
|
||||
<main className="min-h-screen">
|
||||
<BlogHeader />
|
||||
|
||||
{/* Hero Section */}
|
||||
<section className="blog-container py-16">
|
||||
<div className="max-w-3xl mx-auto text-center">
|
||||
<h1 className="text-h1 font-logo text-carbon-950 dark:text-mulberry-100 mb-6">
|
||||
Informed Agentic AI
|
||||
</h1>
|
||||
<p className="text-xl text-carbon-700 dark:text-carbon-300 leading-relaxed">
|
||||
Deep dives into AI orchestration, agent coordination, and the future of
|
||||
intelligent systems from the team building CHORUS.
|
||||
</p>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{/* Featured Posts */}
|
||||
{featuredPosts.length > 0 && (
|
||||
<section className="blog-container py-8">
|
||||
<h2 className="text-h3 font-logo text-carbon-950 dark:text-carbon-100 mb-8">Featured Posts</h2>
|
||||
<div className="grid grid-cols-1 md:grid-cols-2 gap-8">
|
||||
{featuredPosts.map((post) => (
|
||||
<PostCard key={post.slug} post={post} featured={true} />
|
||||
))}
|
||||
</div>
|
||||
</section>
|
||||
)}
|
||||
|
||||
{/* Recent Posts */}
|
||||
<section className="blog-container py-12">
|
||||
<h2 className="text-h3 font-logo text-carbon-950 dark:text-carbon-100 mb-8">Recent Posts</h2>
|
||||
{recentPosts.length > 0 ? (
|
||||
<div className="grid grid-cols-1 md:grid-cols-2 gap-8">
|
||||
{recentPosts.map((post) => (
|
||||
<PostCard key={post.slug} post={post} />
|
||||
))}
|
||||
</div>
|
||||
) : (
|
||||
<div className="text-center py-12">
|
||||
<div className="w-16 h-16 bg-carbon-200 dark:bg-carbon-800 rounded-full flex items-center justify-center mx-auto mb-4">
|
||||
<svg className="w-8 h-8 text-carbon-600 dark:text-carbon-600" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M15.232 5.232l3.536 3.536m-2.036-5.036a2.5 2.5 0 113.536 3.536L6.5 21.036H3v-3.572L16.732 3.732z" />
|
||||
</svg>
|
||||
</div>
|
||||
<h3 className="text-h5 font-semibold text-carbon-950 dark:text-carbon-200 mb-2">Coming Soon</h3>
|
||||
<p className="text-carbon-600 dark:text-carbon-400 max-w-md mx-auto">
|
||||
We're preparing some excellent content about contextual AI and agent orchestration.
|
||||
Check back soon for our first posts!
|
||||
</p>
|
||||
</div>
|
||||
)}
|
||||
</section>
|
||||
|
||||
<BlogFooter />
|
||||
</main>
|
||||
)
|
||||
}
|
||||
174
app/posts/[slug]/page.tsx
Normal file
@@ -0,0 +1,174 @@
|
||||
import { notFound } from 'next/navigation'
|
||||
import { MDXRemote } from 'next-mdx-remote/rsc'
|
||||
import { getPostData, getAllPostSlugs } from '@/lib/blog'
|
||||
import BlogHeader from '@/components/BlogHeader'
|
||||
import BlogFooter from '@/components/BlogFooter'
|
||||
import Link from 'next/link'
|
||||
import remarkGfm from 'remark-gfm'
|
||||
import rehypeHighlight from 'rehype-highlight'
|
||||
import rehypeSlug from 'rehype-slug'
|
||||
import rehypeAutolinkHeadings from 'rehype-autolink-headings'
|
||||
|
||||
interface PostPageProps {
|
||||
params: Promise<{
|
||||
slug: string
|
||||
}>
|
||||
}
|
||||
|
||||
export async function generateStaticParams() {
|
||||
const slugs = getAllPostSlugs()
|
||||
return slugs.map(({ params }) => ({ slug: params.slug }))
|
||||
}
|
||||
|
||||
export async function generateMetadata({ params }: PostPageProps) {
|
||||
const { slug } = await params
|
||||
const post = getPostData(slug)
|
||||
|
||||
if (!post) {
|
||||
return {
|
||||
title: 'Post Not Found - CHORUS PING!'
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
title: `${post.title} - CHORUS PING!`,
|
||||
description: post.description,
|
||||
openGraph: {
|
||||
title: post.title,
|
||||
description: post.description,
|
||||
type: 'article',
|
||||
publishedTime: post.date,
|
||||
authors: [post.author?.name || 'CHORUS Team'],
|
||||
tags: post.tags,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
export default async function PostPage({ params }: PostPageProps) {
|
||||
const { slug } = await params
|
||||
const post = getPostData(slug)
|
||||
|
||||
if (!post) {
|
||||
notFound()
|
||||
}
|
||||
|
||||
const formattedDate = new Date(post.date).toLocaleDateString('en-US', {
|
||||
year: 'numeric',
|
||||
month: 'long',
|
||||
day: 'numeric'
|
||||
})
|
||||
|
||||
const mdxOptions = {
|
||||
mdxOptions: {
|
||||
remarkPlugins: [remarkGfm],
|
||||
rehypePlugins: [
|
||||
rehypeHighlight,
|
||||
rehypeSlug,
|
||||
[rehypeAutolinkHeadings, { behavior: 'wrap' }]
|
||||
],
|
||||
}
|
||||
}
|
||||
|
||||
return (
|
||||
<main className="min-h-screen">
|
||||
<BlogHeader />
|
||||
|
||||
<article className="blog-container py-12">
|
||||
{/* Back link */}
|
||||
<div className="mb-8">
|
||||
<Link
|
||||
href="/"
|
||||
className="inline-flex items-center text-carbon-600 dark:text-carbon-400 hover:text-carbon-950 dark:hover:text-carbon-200 transition-colors text-sm group"
|
||||
>
|
||||
<svg
|
||||
className="w-4 h-4 mr-2 group-hover:-translate-x-1 transition-transform"
|
||||
fill="none"
|
||||
stroke="currentColor"
|
||||
viewBox="0 0 24 24"
|
||||
>
|
||||
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M15 19l-7-7 7-7" />
|
||||
</svg>
|
||||
Back to all posts
|
||||
</Link>
|
||||
</div>
|
||||
|
||||
{/* Article header */}
|
||||
<header className="mb-12 max-w-4xl">
|
||||
<div className="flex flex-wrap gap-2 mb-4">
|
||||
{post.tags.map((tag) => (
|
||||
<span key={tag} className="blog-tag">
|
||||
{tag}
|
||||
</span>
|
||||
))}
|
||||
</div>
|
||||
|
||||
<h1 className="text-h1 font-logo text-carbon-950 dark:text-mulberry-100 mb-6">
|
||||
{post.title}
|
||||
</h1>
|
||||
|
||||
<p className="text-xl text-carbon-700 dark:text-carbon-300 leading-relaxed mb-8">
|
||||
{post.description}
|
||||
</p>
|
||||
|
||||
<div className="flex items-center justify-between border-b border-carbon-300 dark:border-carbon-800 pb-8">
|
||||
<div className="flex items-center space-x-4">
|
||||
<div className="w-12 h-12 bg-gradient-to-br from-mulberry-400 to-ocean-500 rounded-full flex items-center justify-center">
|
||||
<span className="text-carbon-950 font-semibold">
|
||||
{post.author.name.charAt(0)}
|
||||
</span>
|
||||
</div>
|
||||
<div>
|
||||
<p className="text-carbon-950 dark:text-carbon-200 font-medium">
|
||||
{post.author.name}
|
||||
</p>
|
||||
{post.author.role && (
|
||||
<p className="text-carbon-600 dark:text-carbon-500 text-sm">
|
||||
{post.author.role}
|
||||
</p>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="blog-meta text-right">
|
||||
<time dateTime={post.date} className="block">
|
||||
{formattedDate}
|
||||
</time>
|
||||
<span className="text-carbon-600 dark:text-carbon-600">
|
||||
{post.readingTime} min read
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</header>
|
||||
|
||||
{/* Article content */}
|
||||
<div className="prose prose-lg max-w-none">
|
||||
<MDXRemote source={post.content} options={mdxOptions} />
|
||||
</div>
|
||||
|
||||
{/* Article footer */}
|
||||
<footer className="mt-16 pt-8 border-t border-carbon-300 dark:border-carbon-800">
|
||||
<div className="text-center">
|
||||
<h3 className="text-h5 font-logo text-carbon-950 dark:text-carbon-100 mb-4">
|
||||
Join the CHORUS Community
|
||||
</h3>
|
||||
<p className="text-carbon-600 dark:text-carbon-400 mb-6 max-w-2xl mx-auto">
|
||||
Stay updated with the latest insights on contextual AI and agent orchestration.
|
||||
Join our waitlist to get early access to the CHORUS platform.
|
||||
</p>
|
||||
<Link
|
||||
href="https://chorus.services"
|
||||
className="inline-flex items-center px-6 py-3 bg-carbon-900 dark:bg-mulberry-700 hover:bg-carbon-800 dark:hover:bg-mulberry-600 text-white dark:text-mulberry-100 rounded-lg font-medium transition-colors"
|
||||
>
|
||||
Join Waitlist
|
||||
<svg className="w-4 h-4 ml-2" 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>
|
||||
</Link>
|
||||
</div>
|
||||
</footer>
|
||||
</article>
|
||||
|
||||
<BlogFooter />
|
||||
</main>
|
||||
)
|
||||
}
|
||||
34
build-and-push.sh
Executable file
@@ -0,0 +1,34 @@
|
||||
#!/bin/bash
|
||||
|
||||
# CHORUS Blog - Build and Push Docker Image
|
||||
# Builds the Docker image and pushes to the private registry
|
||||
|
||||
set -e
|
||||
|
||||
REGISTRY="registry.home.deepblack.cloud"
|
||||
IMAGE_NAME="tony/chorus-blog"
|
||||
TAG=${1:-latest}
|
||||
FULL_IMAGE="${REGISTRY}/${IMAGE_NAME}:${TAG}"
|
||||
|
||||
echo "🎵 Building CHORUS Blog Docker image..."
|
||||
echo "📦 Image: ${FULL_IMAGE}"
|
||||
echo ""
|
||||
|
||||
# Build the Docker image
|
||||
echo "🔨 Building Docker image..."
|
||||
docker build -t "${FULL_IMAGE}" .
|
||||
|
||||
echo "✅ Build complete!"
|
||||
echo ""
|
||||
|
||||
# Push to registry
|
||||
echo "📤 Pushing to registry..."
|
||||
docker push "${FULL_IMAGE}"
|
||||
|
||||
echo "✅ Push complete!"
|
||||
echo ""
|
||||
echo "🚀 Image ready for deployment:"
|
||||
echo " ${FULL_IMAGE}"
|
||||
echo ""
|
||||
echo "To deploy to Docker Swarm:"
|
||||
echo " docker stack deploy -c ../../../docker/docker-compose.swarm.yml chorus"
|
||||
91
components/BlogFooter.tsx
Normal file
@@ -0,0 +1,91 @@
|
||||
import Link from 'next/link'
|
||||
import ThreeLogo from './ThreeLogo'
|
||||
|
||||
export default function BlogFooter() {
|
||||
return (
|
||||
<footer className="bg-white/80 dark:bg-carbon-950/80 backdrop-blur-md border-t border-carbon-200/50 dark:border-carbon-800/50 mt-24">
|
||||
<div className="blog-container py-12">
|
||||
<div className="grid grid-cols-1 md:grid-cols-4 gap-8">
|
||||
<div className="col-span-1 md:col-span-2">
|
||||
<div className="flex items-center space-x-3 mb-4">
|
||||
<div className="w-10 h-10">
|
||||
<ThreeLogo className="w-full h-full" />
|
||||
</div>
|
||||
<div className="flex flex-col">
|
||||
<span className="font-logo font-semibold text-lg leading-none text-carbon-900 dark:text-carbon-100">CHORUS</span>
|
||||
<span className="text-carbon-600 dark:text-carbon-500 text-xs font-medium">PING!</span>
|
||||
</div>
|
||||
</div>
|
||||
<p className="text-carbon-600 dark:text-carbon-400 text-sm leading-relaxed mb-6 max-w-md">
|
||||
Insights and deep dives into contextual AI orchestration, agent coordination,
|
||||
and the future of intelligent systems.
|
||||
</p>
|
||||
<div className="flex space-x-4">
|
||||
<Link
|
||||
href="https://www.linkedin.com/in/anthonylewisrawlins"
|
||||
className="text-carbon-600 dark:text-carbon-500 hover:text-carbon-800 dark:hover:text-carbon-300 transition-colors"
|
||||
>
|
||||
<span className="sr-only">LinkedIn</span>
|
||||
<svg className="w-5 h-5" fill="currentColor" viewBox="0 0 20 20">
|
||||
<path fillRule="evenodd" d="M16.338 16.338H13.67V12.16c0-.995-.017-2.277-1.387-2.277-1.39 0-1.601 1.086-1.601 2.207v4.248H8.014v-8.59h2.559v1.174h.037c.356-.675 1.227-1.387 2.526-1.387 2.703 0 3.203 1.778 3.203 4.092v4.711zM5.005 6.575a1.548 1.548 0 11-.003-3.096 1.548 1.548 0 01.003 3.096zm-1.337 9.763H6.34v-8.59H3.667v8.59zM17.668 1H2.328C1.595 1 1 1.581 1 2.298v15.403C1 18.418 1.595 19 2.328 19h15.34c.734 0 1.332-.582 1.332-1.299V2.298C19 1.581 18.402 1 17.668 1z" clipRule="evenodd"/>
|
||||
</svg>
|
||||
</Link>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<h3 className="text-carbon-900 dark:text-carbon-100 font-semibold mb-4">Blog</h3>
|
||||
<ul className="space-y-2 text-sm">
|
||||
<li>
|
||||
<Link href="/" className="text-carbon-600 dark:text-carbon-400 hover:text-carbon-800 dark:hover:text-carbon-200 transition-colors">
|
||||
All Posts
|
||||
</Link>
|
||||
</li>
|
||||
<li>
|
||||
<Link href="/tags" className="text-carbon-600 dark:text-carbon-400 hover:text-carbon-800 dark:hover:text-carbon-200 transition-colors">
|
||||
Topics
|
||||
</Link>
|
||||
</li>
|
||||
<li>
|
||||
<Link href="/rss.xml" className="text-carbon-600 dark:text-carbon-400 hover:text-carbon-800 dark:hover:text-carbon-200 transition-colors">
|
||||
RSS Feed
|
||||
</Link>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<h3 className="text-carbon-900 dark:text-carbon-100 font-semibold mb-4">CHORUS</h3>
|
||||
<ul className="space-y-2 text-sm">
|
||||
<li>
|
||||
<Link href="https://chorus.services" className="text-carbon-600 dark:text-carbon-400 hover:text-carbon-800 dark:hover:text-carbon-200 transition-colors">
|
||||
Platform
|
||||
</Link>
|
||||
</li>
|
||||
<li>
|
||||
<Link href="https://chorus.services/about" className="text-carbon-600 dark:text-carbon-400 hover:text-carbon-800 dark:hover:text-carbon-200 transition-colors">
|
||||
About
|
||||
</Link>
|
||||
</li>
|
||||
<li>
|
||||
<Link href="https://chorus.services/contact" className="text-carbon-600 dark:text-carbon-400 hover:text-carbon-800 dark:hover:text-carbon-200 transition-colors">
|
||||
Contact
|
||||
</Link>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="border-t border-carbon-200 dark:border-carbon-800 mt-8 pt-8 text-center">
|
||||
<p className="text-carbon-600 dark:text-carbon-500 text-sm">
|
||||
© {new Date().getFullYear()} CHORUS Services. Built with care by{' '}
|
||||
<Link href="https://deepblack.cloud" className="text-carbon-700 dark:text-carbon-400 hover:text-carbon-900 dark:hover:text-carbon-200 transition-colors">
|
||||
Deep Black Cloud
|
||||
</Link>
|
||||
.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</footer>
|
||||
)
|
||||
}
|
||||
72
components/BlogHeader.tsx
Normal file
@@ -0,0 +1,72 @@
|
||||
'use client'
|
||||
|
||||
import Link from 'next/link'
|
||||
import { useState, useEffect } from 'react'
|
||||
import ThreeLogo from './ThreeLogo'
|
||||
import ThemeToggle from './ThemeToggle'
|
||||
|
||||
export default function BlogHeader() {
|
||||
const [isScrolled, setIsScrolled] = useState(false)
|
||||
|
||||
useEffect(() => {
|
||||
const handleScroll = () => {
|
||||
setIsScrolled(window.scrollY > 0)
|
||||
}
|
||||
|
||||
window.addEventListener('scroll', handleScroll)
|
||||
return () => window.removeEventListener('scroll', handleScroll)
|
||||
}, [])
|
||||
|
||||
return (
|
||||
<header className={`sticky top-0 z-50 transition-all duration-300 ${
|
||||
isScrolled
|
||||
? 'bg-white/80 dark:bg-carbon-950/80 backdrop-blur-md border-b border-carbon-200/50 dark:border-carbon-800/50'
|
||||
: 'bg-white/20 dark:bg-carbon-950/20 backdrop-blur-sm'
|
||||
}`}>
|
||||
<nav className="blog-container py-4">
|
||||
<div className="flex items-center justify-between">
|
||||
<Link href="/" className="flex items-center space-x-3 group">
|
||||
<div className="w-14 h-14 group-hover:scale-110 transition-transform">
|
||||
<ThreeLogo className="w-full h-full" />
|
||||
</div>
|
||||
<div className="flex flex-col">
|
||||
<span className="font-logo font-semibold text-lg leading-none text-carbon-900 dark:text-carbon-100">CHORUS</span>
|
||||
<span className="text-carbon-600 dark:text-carbon-500 text-xs font-medium">PING!</span>
|
||||
</div>
|
||||
</Link>
|
||||
|
||||
<div className="hidden md:flex items-center space-x-8">
|
||||
<Link
|
||||
href="/"
|
||||
className="text-carbon-600 dark:text-carbon-300 hover:text-carbon-900 dark:hover:text-carbon-100 transition-colors font-medium"
|
||||
>
|
||||
All Posts
|
||||
</Link>
|
||||
<Link
|
||||
href="/tags"
|
||||
className="text-carbon-600 dark:text-carbon-300 hover:text-carbon-900 dark:hover:text-carbon-100 transition-colors font-medium"
|
||||
>
|
||||
Topics
|
||||
</Link>
|
||||
<Link
|
||||
href="https://chorus.services"
|
||||
className="text-carbon-600 dark:text-carbon-300 hover:text-carbon-900 dark:hover:text-carbon-100 transition-colors font-medium"
|
||||
>
|
||||
About CHORUS
|
||||
</Link>
|
||||
</div>
|
||||
|
||||
<div className="flex items-center space-x-4">
|
||||
<ThemeToggle />
|
||||
<Link
|
||||
href="https://chorus.services"
|
||||
className="px-4 py-2 bg-carbon-900 dark:bg-mulberry-700 hover:bg-carbon-800 dark:hover:bg-mulberry-600 text-white dark:text-mulberry-100 rounded-lg font-medium transition-colors text-sm"
|
||||
>
|
||||
Join Waitlist
|
||||
</Link>
|
||||
</div>
|
||||
</div>
|
||||
</nav>
|
||||
</header>
|
||||
)
|
||||
}
|
||||
87
components/PostCard.tsx
Normal file
@@ -0,0 +1,87 @@
|
||||
import Link from 'next/link'
|
||||
import { BlogPost } from '@/types/blog'
|
||||
|
||||
interface PostCardProps {
|
||||
post: BlogPost
|
||||
featured?: boolean
|
||||
}
|
||||
|
||||
export default function PostCard({ post, featured = false }: PostCardProps) {
|
||||
const formattedDate = new Date(post.date).toLocaleDateString('en-US', {
|
||||
year: 'numeric',
|
||||
month: 'long',
|
||||
day: 'numeric'
|
||||
})
|
||||
|
||||
return (
|
||||
<article className={`group ${
|
||||
featured
|
||||
? 'bg-carbon-50 dark:bg-carbon-900 border border-carbon-200 dark:border-carbon-800 rounded-xl p-8 hover:border-carbon-400 dark:hover:border-mulberry-700 transition-all duration-300'
|
||||
: 'bg-carbon-100/50 dark:bg-carbon-900/50 border border-carbon-200/50 dark:border-carbon-800/50 rounded-lg p-6 hover:bg-carbon-50 dark:hover:bg-carbon-900 hover:border-carbon-300 dark:hover:border-carbon-700 transition-all duration-300'
|
||||
}`}>
|
||||
<Link href={`/posts/${post.slug}`} className="block">
|
||||
<div className="mb-4">
|
||||
<div className="flex items-center justify-between mb-3">
|
||||
<div className="blog-meta">
|
||||
<time dateTime={post.date} className="text-carbon-600 dark:text-carbon-500">
|
||||
{formattedDate}
|
||||
</time>
|
||||
<span className="text-carbon-500 dark:text-carbon-600">•</span>
|
||||
<span className="text-carbon-600 dark:text-carbon-500">
|
||||
{post.readingTime} min read
|
||||
</span>
|
||||
</div>
|
||||
{post.featured && (
|
||||
<span className="blog-tag bg-mulberry-700 text-mulberry-200">
|
||||
Featured
|
||||
</span>
|
||||
)}
|
||||
</div>
|
||||
|
||||
<h2 className={`${
|
||||
featured ? 'text-h3' : 'text-h4'
|
||||
} font-logo text-carbon-950 dark:text-carbon-100 group-hover:text-carbon-700 dark:group-hover:text-mulberry-200 transition-colors mb-3`}>
|
||||
{post.title}
|
||||
</h2>
|
||||
|
||||
<p className="text-carbon-700 dark:text-carbon-300 leading-relaxed mb-4 line-clamp-3">
|
||||
{post.description}
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div className="flex items-center justify-between">
|
||||
<div className="flex items-center space-x-2">
|
||||
<div className="w-8 h-8 bg-gradient-to-br from-mulberry-400 to-ocean-500 rounded-full flex items-center justify-center">
|
||||
<span className="text-carbon-950 font-semibold text-xs">
|
||||
{post.author?.name?.charAt(0) || 'C'}
|
||||
</span>
|
||||
</div>
|
||||
<div>
|
||||
<p className="text-carbon-950 dark:text-carbon-200 font-medium text-sm">
|
||||
{post.author?.name || 'CHORUS Team'}
|
||||
</p>
|
||||
{post.author?.role && (
|
||||
<p className="text-carbon-600 dark:text-carbon-500 text-xs">
|
||||
{post.author.role}
|
||||
</p>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="flex flex-wrap gap-2">
|
||||
{post.tags?.slice(0, 3).map((tag) => (
|
||||
<span key={tag} className="blog-tag">
|
||||
{tag}
|
||||
</span>
|
||||
)) || []}
|
||||
{(post.tags?.length || 0) > 3 && (
|
||||
<span className="text-carbon-600 dark:text-carbon-500 text-xs">
|
||||
+{(post.tags?.length || 0) - 3} more
|
||||
</span>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
</Link>
|
||||
</article>
|
||||
)
|
||||
}
|
||||
58
components/ThemeToggle.tsx
Normal file
@@ -0,0 +1,58 @@
|
||||
'use client'
|
||||
|
||||
import React, { useState, useEffect } from 'react'
|
||||
|
||||
export default function ThemeToggle() {
|
||||
const [theme, setTheme] = useState<'light' | 'dark'>('dark')
|
||||
|
||||
useEffect(() => {
|
||||
// Check for saved theme preference or default to dark
|
||||
const savedTheme = localStorage.getItem('theme') as 'light' | 'dark' | null
|
||||
const prefersDark = window.matchMedia('(prefers-color-scheme: dark)').matches
|
||||
const initialTheme = savedTheme || (prefersDark ? 'dark' : 'light')
|
||||
|
||||
setTheme(initialTheme)
|
||||
|
||||
// Apply theme to document
|
||||
if (initialTheme === 'dark') {
|
||||
document.documentElement.classList.add('dark')
|
||||
} else {
|
||||
document.documentElement.classList.remove('dark')
|
||||
}
|
||||
}, [])
|
||||
|
||||
const toggleTheme = () => {
|
||||
const newTheme = theme === 'dark' ? 'light' : 'dark'
|
||||
setTheme(newTheme)
|
||||
|
||||
// Save to localStorage
|
||||
localStorage.setItem('theme', newTheme)
|
||||
|
||||
// Apply to document
|
||||
if (newTheme === 'dark') {
|
||||
document.documentElement.classList.add('dark')
|
||||
} else {
|
||||
document.documentElement.classList.remove('dark')
|
||||
}
|
||||
}
|
||||
|
||||
return (
|
||||
<button
|
||||
onClick={toggleTheme}
|
||||
className="p-chorus-sm hover:bg-black/10 dark:hover:bg-white/10 transition-colors rounded-lg backdrop-blur-sm bg-white/20 dark:bg-black/20 border border-white/30 dark:border-white/20"
|
||||
aria-label="Toggle theme"
|
||||
>
|
||||
{theme === 'dark' ? (
|
||||
// Sun icon for switching to light mode
|
||||
<svg className="w-5 h-5 text-white" fill="none" stroke="currentColor" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
|
||||
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M12 3v1m0 16v1m9-9h-1M4 12H3m15.364 6.364l-.707-.707M6.343 6.343l-.707-.707m12.728 0l-.707.707M6.343 17.657l-.707.707M16 12a4 4 0 11-8 0 4 4 0 018 0z" />
|
||||
</svg>
|
||||
) : (
|
||||
// Moon icon for switching to dark mode
|
||||
<svg className="w-5 h-5 text-carbon-950" fill="none" stroke="currentColor" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
|
||||
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M20.354 15.354A9 9 0 018.646 3.646 9.003 9.003 0 0012 21a9.003 9.003 0 008.354-5.646z" />
|
||||
</svg>
|
||||
)}
|
||||
</button>
|
||||
)
|
||||
}
|
||||
236
components/ThreeLogo.tsx
Normal file
@@ -0,0 +1,236 @@
|
||||
'use client';
|
||||
|
||||
import { useEffect, useRef } from 'react';
|
||||
import * as THREE from 'three';
|
||||
import { GLTFLoader } from 'three/examples/jsm/loaders/GLTFLoader.js';
|
||||
import { DRACOLoader } from 'three/examples/jsm/loaders/DRACOLoader.js';
|
||||
|
||||
interface ThreeLogoProps {
|
||||
className?: string;
|
||||
}
|
||||
|
||||
export default function ThreeLogo({ className = "" }: ThreeLogoProps) {
|
||||
const containerRef = useRef<HTMLDivElement | null>(null);
|
||||
|
||||
useEffect(() => {
|
||||
if (!containerRef.current) return;
|
||||
|
||||
const container = containerRef.current;
|
||||
|
||||
// Scene / Renderer / Camera
|
||||
const scene = new THREE.Scene();
|
||||
const camera = new THREE.PerspectiveCamera(45, 1, 0.1, 100);
|
||||
camera.position.set(0, 0, 3.0); // Move camera back to prevent clipping
|
||||
camera.lookAt(0, 0, 0); // Ensure camera looks at exact center
|
||||
|
||||
const renderer = new THREE.WebGLRenderer({ antialias: true, alpha: true });
|
||||
renderer.setPixelRatio(window.devicePixelRatio);
|
||||
renderer.setClearColor(0x000000, 0); // transparent background
|
||||
container.appendChild(renderer.domElement);
|
||||
|
||||
// Resize handling with proper aspect ratio
|
||||
const resize = () => {
|
||||
const { clientWidth, clientHeight } = container;
|
||||
// Ensure square aspect ratio for the logo
|
||||
const size = Math.min(clientWidth, clientHeight);
|
||||
renderer.setSize(size, size, false);
|
||||
camera.aspect = 1; // Always square
|
||||
camera.updateProjectionMatrix();
|
||||
};
|
||||
resize();
|
||||
window.addEventListener('resize', resize);
|
||||
|
||||
// Exact lighting setup from your reference logo.html
|
||||
const light = new THREE.PointLight(0xffffff, 1.4);
|
||||
light.position.set(0, 4, 1);
|
||||
scene.add(light);
|
||||
|
||||
const bottomLight = new THREE.PointLight(0x800080, 1.2, 12);
|
||||
bottomLight.position.set(0, -4, 1);
|
||||
scene.add(bottomLight);
|
||||
|
||||
const leftLight = new THREE.PointLight(0x808000, 1.45, 5);
|
||||
leftLight.position.set(-5, 0, 4);
|
||||
scene.add(leftLight);
|
||||
|
||||
scene.add(new THREE.AmbientLight(0xffffff, 0.45));
|
||||
|
||||
// Load environment map from your horizon gradient image
|
||||
const expandGradient = (img: HTMLImageElement) => {
|
||||
const canvas = document.createElement('canvas');
|
||||
const w = 512, h = 256; // safe HDRI-like size
|
||||
canvas.width = w;
|
||||
canvas.height = h;
|
||||
const ctx = canvas.getContext('2d')!;
|
||||
|
||||
// Stretch the narrow gradient strip to fill the canvas
|
||||
ctx.drawImage(img, 0, 0, w, h);
|
||||
|
||||
return new THREE.CanvasTexture(canvas);
|
||||
};
|
||||
|
||||
const envLoader = new THREE.ImageLoader();
|
||||
envLoader.load('/logos/horizon-gradient.png', (image) => {
|
||||
const tex = expandGradient(image);
|
||||
tex.mapping = THREE.EquirectangularReflectionMapping;
|
||||
|
||||
// Generate proper environment map using PMREM
|
||||
const pmrem = new THREE.PMREMGenerator(renderer);
|
||||
const envMap = pmrem.fromEquirectangular(tex).texture;
|
||||
|
||||
scene.environment = envMap;
|
||||
pmrem.dispose();
|
||||
});
|
||||
|
||||
scene.background = null; // keep transparent
|
||||
|
||||
// Theme-aware material colors
|
||||
const getThemeMaterial = (theme: string = 'default') => {
|
||||
const colorMap = {
|
||||
'default': 0x333333,
|
||||
'protanopia': 0x1e40af, // Blue-800 for red-blind
|
||||
'deuteranopia': 0x6b21a8, // Purple-800 for green-blind
|
||||
'tritanopia': 0x991b1b, // Red-800 for blue-blind
|
||||
'achromatopsia': 0x374151, // Gray-700 for color-blind
|
||||
};
|
||||
|
||||
return new THREE.MeshPhysicalMaterial({
|
||||
color: colorMap[theme as keyof typeof colorMap] || colorMap.default,
|
||||
roughness: 0.24,
|
||||
metalness: 1.0,
|
||||
clearcoat: 0.48,
|
||||
clearcoatRoughness: 0.15,
|
||||
reflectivity: 1.2,
|
||||
sheen: 0.35,
|
||||
sheenColor: new THREE.Color(0x212121),
|
||||
sheenRoughness: 0.168,
|
||||
envMapIntensity: 1,
|
||||
});
|
||||
};
|
||||
|
||||
// Initialize with default material
|
||||
let currentMaterial = getThemeMaterial('default');
|
||||
|
||||
// Load GLB with DRACO support
|
||||
const loader = new GLTFLoader();
|
||||
const draco = new DRACOLoader();
|
||||
draco.setDecoderPath('/draco/');
|
||||
loader.setDRACOLoader(draco);
|
||||
|
||||
let model: THREE.Object3D | null = null;
|
||||
|
||||
console.log('Loading your mobius-ring.glb...');
|
||||
loader.load(
|
||||
'/logos/mobius-ring.glb',
|
||||
(gltf) => {
|
||||
console.log('🎉 Your GLB loaded successfully!', gltf);
|
||||
model = gltf.scene;
|
||||
|
||||
// Apply the theme-aware material
|
||||
model.traverse((child) => {
|
||||
if ((child as THREE.Mesh).isMesh) {
|
||||
(child as THREE.Mesh).material = currentMaterial;
|
||||
}
|
||||
});
|
||||
|
||||
// Center the model exactly at origin
|
||||
const box = new THREE.Box3().setFromObject(model);
|
||||
const center = box.getCenter(new THREE.Vector3());
|
||||
model.position.sub(center); // Move model so its center is at (0,0,0)
|
||||
|
||||
scene.add(model);
|
||||
console.log('🎯 Your Möbius GLB model added to scene and centered at origin');
|
||||
},
|
||||
(progress) => {
|
||||
if (progress.total > 0) {
|
||||
const percent = Math.round(progress.loaded / progress.total * 100);
|
||||
console.log(`GLB loading progress: ${percent}% (${progress.loaded}/${progress.total} bytes)`);
|
||||
}
|
||||
},
|
||||
(err) => {
|
||||
console.error('❌ GLB load error:', err);
|
||||
|
||||
// Fallback: create a torus geometry with the theme-aware material
|
||||
console.log('Creating fallback torus geometry...');
|
||||
const fallbackGeometry = new THREE.TorusGeometry(0.6, 0.2, 16, 100);
|
||||
const fallbackMesh = new THREE.Mesh(fallbackGeometry, currentMaterial);
|
||||
fallbackMesh.position.set(0, 0, 0); // Ensure fallback is also centered
|
||||
scene.add(fallbackMesh);
|
||||
model = fallbackMesh;
|
||||
|
||||
console.log('⚠️ Fallback torus geometry created (placeholder for your GLB)');
|
||||
}
|
||||
);
|
||||
|
||||
// Listen for accessibility theme changes
|
||||
const handleThemeChange = (event: any) => {
|
||||
const newTheme = event.detail.theme;
|
||||
const newMaterial = getThemeMaterial(newTheme);
|
||||
|
||||
if (model) {
|
||||
// Update material on all meshes
|
||||
model.traverse((child: any) => {
|
||||
if (child.isMesh) {
|
||||
child.material.dispose(); // Clean up old material
|
||||
child.material = newMaterial;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// Update current material reference
|
||||
currentMaterial = newMaterial;
|
||||
console.log(`🎨 Logo theme changed to: ${newTheme}`);
|
||||
};
|
||||
|
||||
window.addEventListener('accessibilityThemeChanged', handleThemeChange);
|
||||
|
||||
let raf = 0;
|
||||
const tick = () => {
|
||||
raf = requestAnimationFrame(tick);
|
||||
|
||||
if (model) {
|
||||
// Use exact rotation parameters from your reference logo.html
|
||||
model.rotation.x += 0.010; // spinSpeedX from params
|
||||
model.rotation.y += -0.010; // spinSpeedY from params
|
||||
model.rotation.z += -0.1; // spinSpeedZ from params
|
||||
}
|
||||
|
||||
renderer.render(scene, camera);
|
||||
};
|
||||
tick();
|
||||
|
||||
// Cleanup
|
||||
return () => {
|
||||
cancelAnimationFrame(raf);
|
||||
window.removeEventListener('resize', resize);
|
||||
window.removeEventListener('accessibilityThemeChanged', handleThemeChange);
|
||||
renderer.dispose();
|
||||
draco.dispose();
|
||||
if (container.contains(renderer.domElement)) {
|
||||
container.removeChild(renderer.domElement);
|
||||
}
|
||||
scene.traverse((obj: any) => {
|
||||
if (obj.geometry) obj.geometry.dispose?.();
|
||||
if (obj.material) {
|
||||
const mats = Array.isArray(obj.material) ? obj.material : [obj.material];
|
||||
mats.forEach((m: any) => m.dispose?.());
|
||||
}
|
||||
});
|
||||
};
|
||||
}, []);
|
||||
|
||||
return (
|
||||
<div
|
||||
ref={containerRef}
|
||||
className={className}
|
||||
style={{
|
||||
width: '100%',
|
||||
height: '100%',
|
||||
aspectRatio: '1 / 1',
|
||||
display: 'flex',
|
||||
alignItems: 'center',
|
||||
justifyContent: 'center'
|
||||
}}
|
||||
/>
|
||||
);
|
||||
}
|
||||
51
content/posts/BeyondRAG.md
Normal file
@@ -0,0 +1,51 @@
|
||||
---
|
||||
title: "Beyond RAG: The Future of AI Context with CHORUS"
|
||||
description: "AI is moving fast, but one of the biggest bottlenecks isn't model size or compute power—it's context management. Here's how CHORUS goes beyond traditional RAG approaches."
|
||||
date: "2025-08-28"
|
||||
author:
|
||||
name: "Anthony Rawlins"
|
||||
role: "CEO & Founder, CHORUS Services"
|
||||
tags:
|
||||
- "contextual-ai"
|
||||
- "RAG"
|
||||
- "context-management"
|
||||
- "hierarchical-reasoning"
|
||||
featured: false
|
||||
---
|
||||
|
||||
AI is moving fast, but one of the biggest bottlenecks isn’t model size or compute power, it’s **context management**.
|
||||
|
||||
For years, **Retrieval-Augmented Generation (RAG)** has been the go-to method for extending large language models (LLMs). By bolting on vector databases and search, RAG helps models pull in relevant documents. It works, but only to a point. Anyone who’s scaled production systems knows the cracks:
|
||||
|
||||
* RAG treats knowledge as flat text snippets, missing relationships and nuance.
|
||||
* Git and other version-control systems capture *code history*, but not the evolving reasoning behind decisions.
|
||||
* Static context caches snap a picture in time, but knowledge and workflows don’t stand still.
|
||||
|
||||
In short: **RAG, Git, and static context snapshots aren’t enough for the next generation of AI.**
|
||||
|
||||
## Why Hierarchical Context Matters
|
||||
|
||||
Knowledge isn’t just a pile of files — it’s layered, temporal, and deeply interconnected. AI systems need to track *how* reasoning unfolds, *why* decisions were made, and *how context evolves over time*. That’s where **Chorus** comes in.
|
||||
|
||||
Instead of treating context as documents to fetch, we treat it as a **living, distributed hierarchy**. Chorus enables agents to share, navigate, and build on structured threads of reasoning across domains and time. It’s not just about retrieval — it’s about orchestration, memory, and continuity.
|
||||
|
||||
## Research Is Moving the Same Way
|
||||
|
||||
The AI research frontier points in this direction too:
|
||||
|
||||
* **NVIDIA’s recent small model papers** showed that scaling up isn’t the only answer — well-designed small models can outperform by being more structured and specialized.
|
||||
* The **Hierarchical Reasoning Model (HRM)** highlights how smarter architectures, not just bigger context windows, unlock deeper reasoning.
|
||||
|
||||
Both emphasize the same principle: **intelligence comes from structure, not size alone**.
|
||||
|
||||
## What’s Next
|
||||
|
||||
Chorus is building the scaffolding for this new paradigm. Our goal is to make context:
|
||||
|
||||
* **Persistent** – reasoning doesn’t vanish when the session ends.
|
||||
* **Navigable** – past decisions and justifications are always accessible.
|
||||
* **Collaborative** – multiple agents can share and evolve context together.
|
||||
|
||||
We’re not giving away the full blueprint yet, but if you’re interested in what lies **beyond RAG**, beyond Git, and beyond static memory hacks, keep watching.
|
||||
|
||||
The future of **AI context management** is closer than you think.
|
||||
67
content/posts/welcome-to-chorus-blog.md
Normal file
@@ -0,0 +1,67 @@
|
||||
---
|
||||
title: "Welcome to PING!"
|
||||
description: "The blog about contextual AI orchestration, agent coordination, and the future of intelligent systems."
|
||||
date: "2025-08-27"
|
||||
author:
|
||||
name: "Anthony Rawlins"
|
||||
role: "CEO & Founder, CHORUS Services"
|
||||
tags:
|
||||
- "announcement"
|
||||
- "contextual-ai"
|
||||
- "orchestration"
|
||||
featured: true
|
||||
---
|
||||
|
||||
We're excited to launch PING! — the blog about contextual AI orchestration, agent coordination, and the future of intelligent systems. This is where we'll share our thoughts, insights, and discoveries as we build the future of contextual AI.
|
||||
|
||||
## What to Expect
|
||||
|
||||
Our blog will cover a range of topics that are central to our mission at CHORUS:
|
||||
|
||||
### Contextual AI Orchestration
|
||||
Deep dives into how we're solving the challenge of getting **the right context, to the right agent, at the right time**. We'll explore the architectural decisions, technical challenges, and innovative solutions that make contextual AI orchestration possible.
|
||||
|
||||
### Agent Coordination
|
||||
Insights into how autonomous agents can work together effectively, including:
|
||||
- **P2P Agent Networks**: How agents discover and coordinate with each other
|
||||
- **Decision Making**: Algorithms and patterns for distributed decision making
|
||||
- **Context Sharing**: Efficient methods for agents to share relevant context
|
||||
|
||||
### Technical Architecture
|
||||
Behind-the-scenes looks at the systems we're building:
|
||||
- **BZZZ**: Our P2P agent coordination platform
|
||||
- **SLURP**: Our context curation and intelligence system
|
||||
- **WHOOSH**: Our orchestration and workflow platform
|
||||
|
||||
### Industry Perspectives
|
||||
Our thoughts on the evolving AI landscape, emerging patterns in agent-based systems, and where we think the industry is heading.
|
||||
|
||||
## Our Philosophy
|
||||
|
||||
At CHORUS, we believe that the future of AI isn't just about making individual models more powerful—it's about creating **intelligent systems** where multiple agents, each with their own specialized capabilities, can work together seamlessly.
|
||||
|
||||
The key insight is **context**. Without the right context, even the most powerful AI agent is just expensive autocomplete. With the right context, even smaller specialized agents can achieve remarkable results.
|
||||
|
||||
## What's Coming Next
|
||||
|
||||
Over the coming weeks and months, we'll be sharing:
|
||||
|
||||
1. **Technical deep dives** into our core systems
|
||||
2. **Case studies** from our development work
|
||||
3. **Tutorials** on building contextual AI systems
|
||||
4. **Industry analysis** on AI orchestration trends
|
||||
5. **Open source releases** and community projects
|
||||
|
||||
## Join the Conversation
|
||||
|
||||
We're building CHORUS in the open, and we want you to be part of the journey. Whether you're an AI researcher, a developer building agent-based systems, or just someone curious about the future of AI, we'd love to hear from you.
|
||||
|
||||
**Stay Connected:**
|
||||
- Join our [waitlist](https://chorus.services) for early access
|
||||
- Connect with us on [LinkedIn](https://linkedin.com/company/chorus-services)
|
||||
|
||||
The future of AI is contextual, distributed, and orchestrated. Let's build it together.
|
||||
|
||||
---
|
||||
|
||||
*Want to learn more about CHORUS? Visit our [main website](https://chorus.services) to explore our vision for contextual AI orchestration.*
|
||||
53
content/scheduled/on-prem-GPUs.md
Normal file
@@ -0,0 +1,53 @@
|
||||
---
|
||||
title: "Why On-prem GPUs Still Matter for AI"
|
||||
description: "Own the stack. Own your data."
|
||||
date: "2025-08-29"
|
||||
author:
|
||||
name: "Anthony Rawlins"
|
||||
role: "CEO & Founder, CHORUS Services"
|
||||
tags:
|
||||
- "gpu compute"
|
||||
- "contextual-ai"
|
||||
- "infrastructure"
|
||||
featured: false
|
||||
---
|
||||
|
||||
Cloud GPUs are everywhere right now, but if you’ve tried to run serious workloads, you know the story: long queues, high costs, throttling, and vendor lock-in. Renting compute might be convenient for prototypes, but at scale it gets expensive and limiting.
|
||||
|
||||
That’s why more teams are rethinking **on-premises GPU infrastructure**.
|
||||
|
||||
## The Case for In-House Compute
|
||||
|
||||
1. **Cost at Scale** – Training, fine-tuning, or heavy inference workloads rack up cloud costs quickly. Owning your own GPUs flips that equation over the long term.
|
||||
2. **Control & Customization** – You own the stack: drivers, runtimes, schedulers, cluster topology. No waiting on cloud providers.
|
||||
3. **Latency & Data Gravity** – Keeping data close to the GPUs removes bandwidth bottlenecks. If your data already lives in-house, shipping it to the cloud and back is wasteful.
|
||||
4. **Privacy & Compliance** – Your models and data stay under your governance. No shared tenancy, no external handling.
|
||||
|
||||
## Not Just About Training Massive LLMs
|
||||
|
||||
It’s easy to think of GPUs as “just for training giant foundation models.” But most teams today are leveraging GPUs for:
|
||||
|
||||
* **Inference at scale** – low-latency deployments.
|
||||
* **Fine-tuning & adapters** – customizing smaller models.
|
||||
* **Vector search & embeddings** – powering RAG pipelines.
|
||||
* **Analytics & graph workloads** – accelerated by frameworks like RAPIDS.
|
||||
|
||||
This is where recent research gets interesting. NVIDIA’s latest papers on **small models** show that capability doesn’t just scale with parameter count — it scales with *specialization and structure*. Instead of defaulting to giant black-box LLMs, we’re entering a world where **smaller, domain-tuned models** run faster, cheaper, and more predictably.
|
||||
|
||||
And with the launch of the **Blackwell architecture**, the GPU landscape itself is changing. Blackwell isn’t just about raw FLOPs; it’s about efficiency, memory bandwidth, and supporting mixed workloads (training + inference + data processing) on the same platform. That’s exactly the kind of balance on-prem clusters can exploit.
|
||||
|
||||
## Where This Ties Back to Chorus
|
||||
|
||||
At Chorus, we think of GPUs not just as horsepower, but as the **substrate that makes distributed reasoning practical**. Hierarchical context and agent orchestration require low-latency, high-throughput compute — the kind that’s tough to guarantee in the cloud. On-prem clusters give us:
|
||||
|
||||
* Predictable performance for multi-agent reasoning.
|
||||
* Dedicated acceleration for embeddings and vector ops.
|
||||
* A foundation for experimenting with **HRM-inspired** approaches that don’t just make models bigger, but make them smarter.
|
||||
|
||||
## The Bottom Line
|
||||
|
||||
The future isn’t cloud *versus* on-prem — it’s hybrid. Cloud for burst capacity, on-prem GPUs for sustained reasoning, privacy, and cost control. Owning your own stack is about **freedom**: the freedom to innovate at your pace, tune your models your way, and build intelligence on infrastructure you trust.
|
||||
|
||||
The real question isn’t whether you *can* run AI on-prem.
|
||||
It’s whether you can afford *not to*.
|
||||
|
||||
30
dev-start.sh
Executable file
@@ -0,0 +1,30 @@
|
||||
#!/bin/bash
|
||||
|
||||
# CHORUS Blog Development Server
|
||||
# Start the Next.js development server for the blog
|
||||
|
||||
set -e
|
||||
|
||||
echo "🎵 Starting CHORUS Blog development server..."
|
||||
|
||||
# Check if we're in the right directory
|
||||
if [ ! -f "package.json" ]; then
|
||||
echo "❌ Error: package.json not found. Are you in the blog directory?"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Install dependencies if node_modules doesn't exist
|
||||
if [ ! -d "node_modules" ]; then
|
||||
echo "📦 Installing dependencies..."
|
||||
npm install
|
||||
fi
|
||||
|
||||
# Start the development server
|
||||
echo "🚀 Starting Next.js development server on port 3002..."
|
||||
echo "📝 Blog will be available at: http://localhost:3002"
|
||||
echo "🌍 Production URL will be: https://blog.chorus.services"
|
||||
echo ""
|
||||
echo "Press Ctrl+C to stop the server"
|
||||
echo ""
|
||||
|
||||
npm run dev
|
||||
34
docker-compose.yml
Normal file
@@ -0,0 +1,34 @@
|
||||
version: '3.8'
|
||||
|
||||
services:
|
||||
chorus-blog:
|
||||
build:
|
||||
context: .
|
||||
dockerfile: Dockerfile
|
||||
ports:
|
||||
- "3002:3000"
|
||||
environment:
|
||||
- NODE_ENV=production
|
||||
- NEXT_TELEMETRY_DISABLED=1
|
||||
volumes:
|
||||
- ./posts:/app/posts:ro
|
||||
- ./scheduled:/app/scheduled:ro
|
||||
- blog_logs:/app/.next/cache
|
||||
labels:
|
||||
- "traefik.enable=true"
|
||||
- "traefik.docker.network=tengig"
|
||||
- "traefik.http.routers.chorus-blog.rule=Host(`blog.chorus.services`)"
|
||||
- "traefik.http.routers.chorus-blog.entrypoints=web-secured"
|
||||
- "traefik.http.routers.chorus-blog.tls.certresolver=letsencryptresolver"
|
||||
- "traefik.http.services.chorus-blog.loadbalancer.server.port=3000"
|
||||
- "traefik.http.services.chorus-blog.loadbalancer.passhostheader=true"
|
||||
networks:
|
||||
- tengig
|
||||
restart: unless-stopped
|
||||
|
||||
volumes:
|
||||
blog_logs:
|
||||
|
||||
networks:
|
||||
tengig:
|
||||
external: true
|
||||
106
lib/blog.ts
Normal file
@@ -0,0 +1,106 @@
|
||||
import fs from 'fs'
|
||||
import path from 'path'
|
||||
import matter from 'gray-matter'
|
||||
import { BlogPost, BlogMeta } from '@/types/blog'
|
||||
|
||||
const postsDirectory = path.join(process.cwd(), 'content/posts')
|
||||
|
||||
export function getSortedPostsData(): BlogPost[] {
|
||||
// Get file names under /content/posts
|
||||
const fileNames = fs.readdirSync(postsDirectory)
|
||||
const allPostsData = fileNames
|
||||
.filter((fileName) => fileName.endsWith('.md'))
|
||||
.map((fileName) => {
|
||||
// Remove ".md" from file name to get id
|
||||
const slug = fileName.replace(/\.md$/, '')
|
||||
|
||||
// Read markdown file as string
|
||||
const fullPath = path.join(postsDirectory, fileName)
|
||||
const fileContents = fs.readFileSync(fullPath, 'utf8')
|
||||
|
||||
// Use gray-matter to parse the post metadata section
|
||||
const matterResult = matter(fileContents)
|
||||
const meta = matterResult.data as BlogMeta
|
||||
|
||||
// Calculate reading time (average 200 words per minute)
|
||||
const wordCount = matterResult.content.split(/\s+/).length
|
||||
const readingTime = Math.ceil(wordCount / 200)
|
||||
|
||||
return {
|
||||
slug,
|
||||
content: matterResult.content,
|
||||
readingTime,
|
||||
...meta,
|
||||
} as BlogPost
|
||||
})
|
||||
|
||||
// Sort posts by date
|
||||
return allPostsData.sort((a, b) => {
|
||||
if (a.date < b.date) {
|
||||
return 1
|
||||
} else {
|
||||
return -1
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
export function getAllPostSlugs() {
|
||||
const fileNames = fs.readdirSync(postsDirectory)
|
||||
return fileNames
|
||||
.filter((fileName) => fileName.endsWith('.md'))
|
||||
.map((fileName) => {
|
||||
return {
|
||||
params: {
|
||||
slug: fileName.replace(/\.md$/, ''),
|
||||
},
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
export function getPostData(slug: string): BlogPost | null {
|
||||
try {
|
||||
const fullPath = path.join(postsDirectory, `${slug}.md`)
|
||||
const fileContents = fs.readFileSync(fullPath, 'utf8')
|
||||
|
||||
// Use gray-matter to parse the post metadata section
|
||||
const matterResult = matter(fileContents)
|
||||
const meta = matterResult.data as BlogMeta
|
||||
|
||||
// Calculate reading time (average 200 words per minute)
|
||||
const wordCount = matterResult.content.split(/\s+/).length
|
||||
const readingTime = Math.ceil(wordCount / 200)
|
||||
|
||||
return {
|
||||
slug,
|
||||
content: matterResult.content,
|
||||
readingTime,
|
||||
...meta,
|
||||
} as BlogPost
|
||||
} catch (error) {
|
||||
console.error(`Error reading post ${slug}:`, error)
|
||||
return null
|
||||
}
|
||||
}
|
||||
|
||||
export function getFeaturedPosts(): BlogPost[] {
|
||||
const allPosts = getSortedPostsData()
|
||||
return allPosts.filter(post => post.featured)
|
||||
}
|
||||
|
||||
export function getPostsByTag(tag: string): BlogPost[] {
|
||||
const allPosts = getSortedPostsData()
|
||||
return allPosts.filter(post =>
|
||||
post.tags.some(t => t.toLowerCase() === tag.toLowerCase())
|
||||
)
|
||||
}
|
||||
|
||||
export function getAllTags(): string[] {
|
||||
const allPosts = getSortedPostsData()
|
||||
const tags = new Set<string>()
|
||||
|
||||
allPosts.forEach(post => {
|
||||
post.tags.forEach(tag => tags.add(tag))
|
||||
})
|
||||
|
||||
return Array.from(tags).sort()
|
||||
}
|
||||
15
next.config.js
Normal file
@@ -0,0 +1,15 @@
|
||||
/** @type {import('next').NextConfig} */
|
||||
const nextConfig = {
|
||||
output: 'standalone',
|
||||
images: {
|
||||
domains: ['blog.chorus.services', 'chorus.services'],
|
||||
},
|
||||
typescript: {
|
||||
ignoreBuildErrors: false,
|
||||
},
|
||||
eslint: {
|
||||
ignoreDuringBuilds: false,
|
||||
},
|
||||
}
|
||||
|
||||
module.exports = nextConfig
|
||||
8486
package-lock.json
generated
Normal file
51
package.json
Normal file
@@ -0,0 +1,51 @@
|
||||
{
|
||||
"name": "chorus-ping",
|
||||
"version": "1.0.0",
|
||||
"description": "CHORUS PING! - Static blog posts using Next.js",
|
||||
"private": true,
|
||||
"scripts": {
|
||||
"dev": "next dev -p 3002",
|
||||
"build": "next build",
|
||||
"start": "next start -p 3002",
|
||||
"lint": "next lint",
|
||||
"type-check": "tsc --noEmit",
|
||||
"docker:build": "docker build -t chorus-blog .",
|
||||
"docker:run": "docker run -p 3002:3000 chorus-blog",
|
||||
"docker:compose": "docker-compose up -d"
|
||||
},
|
||||
"dependencies": {
|
||||
"@types/node": "^20.0.0",
|
||||
"@types/react": "^18.0.0",
|
||||
"@types/react-dom": "^18.0.0",
|
||||
"@types/three": "^0.179.0",
|
||||
"autoprefixer": "^10.4.0",
|
||||
"clsx": "^2.1.0",
|
||||
"gray-matter": "^4.0.3",
|
||||
"next": "^14.2.18",
|
||||
"next-mdx-remote": "^5.0.0",
|
||||
"postcss": "^8.4.0",
|
||||
"react": "^18.0.0",
|
||||
"react-dom": "^18.0.0",
|
||||
"rehype-autolink-headings": "^7.0.0",
|
||||
"rehype-highlight": "^7.0.0",
|
||||
"rehype-slug": "^6.0.0",
|
||||
"remark-gfm": "^4.0.0",
|
||||
"tailwindcss": "^3.4.0",
|
||||
"three": "^0.179.1",
|
||||
"typescript": "^5.0.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@tailwindcss/typography": "^0.5.0",
|
||||
"eslint": "^8.0.0",
|
||||
"eslint-config-next": "^15.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=18.0.0"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "http://ironwood:3000/tony/chorus.services.git"
|
||||
},
|
||||
"author": "Anthony Lewis Rawlins <cto@deepblack.cloud>",
|
||||
"license": "PROPRIETARY"
|
||||
}
|
||||
6
postcss.config.js
Normal file
@@ -0,0 +1,6 @@
|
||||
module.exports = {
|
||||
plugins: {
|
||||
tailwindcss: {},
|
||||
autoprefixer: {},
|
||||
},
|
||||
}
|
||||
BIN
public/android-chrome-192x192.png
Normal file
|
After Width: | Height: | Size: 26 KiB |
BIN
public/android-chrome-512x512.png
Normal file
|
After Width: | Height: | Size: 106 KiB |
BIN
public/apple-touch-icon.png
Normal file
|
After Width: | Height: | Size: 24 KiB |
32
public/draco/README.md
Normal file
@@ -0,0 +1,32 @@
|
||||
# Draco 3D Data Compression
|
||||
|
||||
Draco is an open-source library for compressing and decompressing 3D geometric meshes and point clouds. It is intended to improve the storage and transmission of 3D graphics.
|
||||
|
||||
[Website](https://google.github.io/draco/) | [GitHub](https://github.com/google/draco)
|
||||
|
||||
## Contents
|
||||
|
||||
This folder contains three utilities:
|
||||
|
||||
* `draco_decoder.js` — Emscripten-compiled decoder, compatible with any modern browser.
|
||||
* `draco_decoder.wasm` — WebAssembly decoder, compatible with newer browsers and devices.
|
||||
* `draco_wasm_wrapper.js` — JavaScript wrapper for the WASM decoder.
|
||||
|
||||
Each file is provided in two variations:
|
||||
|
||||
* **Default:** Latest stable builds, tracking the project's [master branch](https://github.com/google/draco).
|
||||
* **glTF:** Builds targeted by the [glTF mesh compression extension](https://github.com/KhronosGroup/glTF/tree/master/extensions/2.0/Khronos/KHR_draco_mesh_compression), tracking the [corresponding Draco branch](https://github.com/google/draco/tree/gltf_2.0_draco_extension).
|
||||
|
||||
Either variation may be used with `DRACOLoader`:
|
||||
|
||||
```js
|
||||
var dracoLoader = new DRACOLoader();
|
||||
dracoLoader.setDecoderPath('path/to/decoders/');
|
||||
dracoLoader.setDecoderConfig({type: 'js'}); // (Optional) Override detection of WASM support.
|
||||
```
|
||||
|
||||
Further [documentation on GitHub](https://github.com/google/draco/tree/master/javascript/example#static-loading-javascript-decoder).
|
||||
|
||||
## License
|
||||
|
||||
[Apache License 2.0](https://github.com/google/draco/blob/master/LICENSE)
|
||||
34
public/draco/draco_decoder.js
Normal file
BIN
public/draco/draco_decoder.wasm
Normal file
33
public/draco/draco_encoder.js
Normal file
117
public/draco/draco_wasm_wrapper.js
Normal file
@@ -0,0 +1,117 @@
|
||||
var $jscomp=$jscomp||{};$jscomp.scope={};$jscomp.arrayIteratorImpl=function(k){var n=0;return function(){return n<k.length?{done:!1,value:k[n++]}:{done:!0}}};$jscomp.arrayIterator=function(k){return{next:$jscomp.arrayIteratorImpl(k)}};$jscomp.makeIterator=function(k){var n="undefined"!=typeof Symbol&&Symbol.iterator&&k[Symbol.iterator];return n?n.call(k):$jscomp.arrayIterator(k)};$jscomp.ASSUME_ES5=!1;$jscomp.ASSUME_NO_NATIVE_MAP=!1;$jscomp.ASSUME_NO_NATIVE_SET=!1;$jscomp.SIMPLE_FROUND_POLYFILL=!1;
|
||||
$jscomp.ISOLATE_POLYFILLS=!1;$jscomp.FORCE_POLYFILL_PROMISE=!1;$jscomp.FORCE_POLYFILL_PROMISE_WHEN_NO_UNHANDLED_REJECTION=!1;$jscomp.getGlobal=function(k){k=["object"==typeof globalThis&&globalThis,k,"object"==typeof window&&window,"object"==typeof self&&self,"object"==typeof global&&global];for(var n=0;n<k.length;++n){var l=k[n];if(l&&l.Math==Math)return l}throw Error("Cannot find global object");};$jscomp.global=$jscomp.getGlobal(this);
|
||||
$jscomp.defineProperty=$jscomp.ASSUME_ES5||"function"==typeof Object.defineProperties?Object.defineProperty:function(k,n,l){if(k==Array.prototype||k==Object.prototype)return k;k[n]=l.value;return k};$jscomp.IS_SYMBOL_NATIVE="function"===typeof Symbol&&"symbol"===typeof Symbol("x");$jscomp.TRUST_ES6_POLYFILLS=!$jscomp.ISOLATE_POLYFILLS||$jscomp.IS_SYMBOL_NATIVE;$jscomp.polyfills={};$jscomp.propertyToPolyfillSymbol={};$jscomp.POLYFILL_PREFIX="$jscp$";
|
||||
var $jscomp$lookupPolyfilledValue=function(k,n){var l=$jscomp.propertyToPolyfillSymbol[n];if(null==l)return k[n];l=k[l];return void 0!==l?l:k[n]};$jscomp.polyfill=function(k,n,l,p){n&&($jscomp.ISOLATE_POLYFILLS?$jscomp.polyfillIsolated(k,n,l,p):$jscomp.polyfillUnisolated(k,n,l,p))};
|
||||
$jscomp.polyfillUnisolated=function(k,n,l,p){l=$jscomp.global;k=k.split(".");for(p=0;p<k.length-1;p++){var h=k[p];if(!(h in l))return;l=l[h]}k=k[k.length-1];p=l[k];n=n(p);n!=p&&null!=n&&$jscomp.defineProperty(l,k,{configurable:!0,writable:!0,value:n})};
|
||||
$jscomp.polyfillIsolated=function(k,n,l,p){var h=k.split(".");k=1===h.length;p=h[0];p=!k&&p in $jscomp.polyfills?$jscomp.polyfills:$jscomp.global;for(var A=0;A<h.length-1;A++){var f=h[A];if(!(f in p))return;p=p[f]}h=h[h.length-1];l=$jscomp.IS_SYMBOL_NATIVE&&"es6"===l?p[h]:null;n=n(l);null!=n&&(k?$jscomp.defineProperty($jscomp.polyfills,h,{configurable:!0,writable:!0,value:n}):n!==l&&(void 0===$jscomp.propertyToPolyfillSymbol[h]&&(l=1E9*Math.random()>>>0,$jscomp.propertyToPolyfillSymbol[h]=$jscomp.IS_SYMBOL_NATIVE?
|
||||
$jscomp.global.Symbol(h):$jscomp.POLYFILL_PREFIX+l+"$"+h),$jscomp.defineProperty(p,$jscomp.propertyToPolyfillSymbol[h],{configurable:!0,writable:!0,value:n})))};
|
||||
$jscomp.polyfill("Promise",function(k){function n(){this.batch_=null}function l(f){return f instanceof h?f:new h(function(q,v){q(f)})}if(k&&(!($jscomp.FORCE_POLYFILL_PROMISE||$jscomp.FORCE_POLYFILL_PROMISE_WHEN_NO_UNHANDLED_REJECTION&&"undefined"===typeof $jscomp.global.PromiseRejectionEvent)||!$jscomp.global.Promise||-1===$jscomp.global.Promise.toString().indexOf("[native code]")))return k;n.prototype.asyncExecute=function(f){if(null==this.batch_){this.batch_=[];var q=this;this.asyncExecuteFunction(function(){q.executeBatch_()})}this.batch_.push(f)};
|
||||
var p=$jscomp.global.setTimeout;n.prototype.asyncExecuteFunction=function(f){p(f,0)};n.prototype.executeBatch_=function(){for(;this.batch_&&this.batch_.length;){var f=this.batch_;this.batch_=[];for(var q=0;q<f.length;++q){var v=f[q];f[q]=null;try{v()}catch(z){this.asyncThrow_(z)}}}this.batch_=null};n.prototype.asyncThrow_=function(f){this.asyncExecuteFunction(function(){throw f;})};var h=function(f){this.state_=0;this.result_=void 0;this.onSettledCallbacks_=[];this.isRejectionHandled_=!1;var q=this.createResolveAndReject_();
|
||||
try{f(q.resolve,q.reject)}catch(v){q.reject(v)}};h.prototype.createResolveAndReject_=function(){function f(z){return function(O){v||(v=!0,z.call(q,O))}}var q=this,v=!1;return{resolve:f(this.resolveTo_),reject:f(this.reject_)}};h.prototype.resolveTo_=function(f){if(f===this)this.reject_(new TypeError("A Promise cannot resolve to itself"));else if(f instanceof h)this.settleSameAsPromise_(f);else{a:switch(typeof f){case "object":var q=null!=f;break a;case "function":q=!0;break a;default:q=!1}q?this.resolveToNonPromiseObj_(f):
|
||||
this.fulfill_(f)}};h.prototype.resolveToNonPromiseObj_=function(f){var q=void 0;try{q=f.then}catch(v){this.reject_(v);return}"function"==typeof q?this.settleSameAsThenable_(q,f):this.fulfill_(f)};h.prototype.reject_=function(f){this.settle_(2,f)};h.prototype.fulfill_=function(f){this.settle_(1,f)};h.prototype.settle_=function(f,q){if(0!=this.state_)throw Error("Cannot settle("+f+", "+q+"): Promise already settled in state"+this.state_);this.state_=f;this.result_=q;2===this.state_&&this.scheduleUnhandledRejectionCheck_();
|
||||
this.executeOnSettledCallbacks_()};h.prototype.scheduleUnhandledRejectionCheck_=function(){var f=this;p(function(){if(f.notifyUnhandledRejection_()){var q=$jscomp.global.console;"undefined"!==typeof q&&q.error(f.result_)}},1)};h.prototype.notifyUnhandledRejection_=function(){if(this.isRejectionHandled_)return!1;var f=$jscomp.global.CustomEvent,q=$jscomp.global.Event,v=$jscomp.global.dispatchEvent;if("undefined"===typeof v)return!0;"function"===typeof f?f=new f("unhandledrejection",{cancelable:!0}):
|
||||
"function"===typeof q?f=new q("unhandledrejection",{cancelable:!0}):(f=$jscomp.global.document.createEvent("CustomEvent"),f.initCustomEvent("unhandledrejection",!1,!0,f));f.promise=this;f.reason=this.result_;return v(f)};h.prototype.executeOnSettledCallbacks_=function(){if(null!=this.onSettledCallbacks_){for(var f=0;f<this.onSettledCallbacks_.length;++f)A.asyncExecute(this.onSettledCallbacks_[f]);this.onSettledCallbacks_=null}};var A=new n;h.prototype.settleSameAsPromise_=function(f){var q=this.createResolveAndReject_();
|
||||
f.callWhenSettled_(q.resolve,q.reject)};h.prototype.settleSameAsThenable_=function(f,q){var v=this.createResolveAndReject_();try{f.call(q,v.resolve,v.reject)}catch(z){v.reject(z)}};h.prototype.then=function(f,q){function v(t,x){return"function"==typeof t?function(D){try{z(t(D))}catch(R){O(R)}}:x}var z,O,ba=new h(function(t,x){z=t;O=x});this.callWhenSettled_(v(f,z),v(q,O));return ba};h.prototype.catch=function(f){return this.then(void 0,f)};h.prototype.callWhenSettled_=function(f,q){function v(){switch(z.state_){case 1:f(z.result_);
|
||||
break;case 2:q(z.result_);break;default:throw Error("Unexpected state: "+z.state_);}}var z=this;null==this.onSettledCallbacks_?A.asyncExecute(v):this.onSettledCallbacks_.push(v);this.isRejectionHandled_=!0};h.resolve=l;h.reject=function(f){return new h(function(q,v){v(f)})};h.race=function(f){return new h(function(q,v){for(var z=$jscomp.makeIterator(f),O=z.next();!O.done;O=z.next())l(O.value).callWhenSettled_(q,v)})};h.all=function(f){var q=$jscomp.makeIterator(f),v=q.next();return v.done?l([]):new h(function(z,
|
||||
O){function ba(D){return function(R){t[D]=R;x--;0==x&&z(t)}}var t=[],x=0;do t.push(void 0),x++,l(v.value).callWhenSettled_(ba(t.length-1),O),v=q.next();while(!v.done)})};return h},"es6","es3");$jscomp.owns=function(k,n){return Object.prototype.hasOwnProperty.call(k,n)};$jscomp.assign=$jscomp.TRUST_ES6_POLYFILLS&&"function"==typeof Object.assign?Object.assign:function(k,n){for(var l=1;l<arguments.length;l++){var p=arguments[l];if(p)for(var h in p)$jscomp.owns(p,h)&&(k[h]=p[h])}return k};
|
||||
$jscomp.polyfill("Object.assign",function(k){return k||$jscomp.assign},"es6","es3");$jscomp.checkStringArgs=function(k,n,l){if(null==k)throw new TypeError("The 'this' value for String.prototype."+l+" must not be null or undefined");if(n instanceof RegExp)throw new TypeError("First argument to String.prototype."+l+" must not be a regular expression");return k+""};
|
||||
$jscomp.polyfill("String.prototype.startsWith",function(k){return k?k:function(n,l){var p=$jscomp.checkStringArgs(this,n,"startsWith");n+="";var h=p.length,A=n.length;l=Math.max(0,Math.min(l|0,p.length));for(var f=0;f<A&&l<h;)if(p[l++]!=n[f++])return!1;return f>=A}},"es6","es3");
|
||||
$jscomp.polyfill("Array.prototype.copyWithin",function(k){function n(l){l=Number(l);return Infinity===l||-Infinity===l?l:l|0}return k?k:function(l,p,h){var A=this.length;l=n(l);p=n(p);h=void 0===h?A:n(h);l=0>l?Math.max(A+l,0):Math.min(l,A);p=0>p?Math.max(A+p,0):Math.min(p,A);h=0>h?Math.max(A+h,0):Math.min(h,A);if(l<p)for(;p<h;)p in this?this[l++]=this[p++]:(delete this[l++],p++);else for(h=Math.min(h,A+p-l),l+=h-p;h>p;)--h in this?this[--l]=this[h]:delete this[--l];return this}},"es6","es3");
|
||||
$jscomp.typedArrayCopyWithin=function(k){return k?k:Array.prototype.copyWithin};$jscomp.polyfill("Int8Array.prototype.copyWithin",$jscomp.typedArrayCopyWithin,"es6","es5");$jscomp.polyfill("Uint8Array.prototype.copyWithin",$jscomp.typedArrayCopyWithin,"es6","es5");$jscomp.polyfill("Uint8ClampedArray.prototype.copyWithin",$jscomp.typedArrayCopyWithin,"es6","es5");$jscomp.polyfill("Int16Array.prototype.copyWithin",$jscomp.typedArrayCopyWithin,"es6","es5");
|
||||
$jscomp.polyfill("Uint16Array.prototype.copyWithin",$jscomp.typedArrayCopyWithin,"es6","es5");$jscomp.polyfill("Int32Array.prototype.copyWithin",$jscomp.typedArrayCopyWithin,"es6","es5");$jscomp.polyfill("Uint32Array.prototype.copyWithin",$jscomp.typedArrayCopyWithin,"es6","es5");$jscomp.polyfill("Float32Array.prototype.copyWithin",$jscomp.typedArrayCopyWithin,"es6","es5");$jscomp.polyfill("Float64Array.prototype.copyWithin",$jscomp.typedArrayCopyWithin,"es6","es5");
|
||||
var DracoDecoderModule=function(){var k="undefined"!==typeof document&&document.currentScript?document.currentScript.src:void 0;"undefined"!==typeof __filename&&(k=k||__filename);return function(n){function l(e){return a.locateFile?a.locateFile(e,U):U+e}function p(e,b,c){var d=b+c;for(c=b;e[c]&&!(c>=d);)++c;if(16<c-b&&e.buffer&&va)return va.decode(e.subarray(b,c));for(d="";b<c;){var g=e[b++];if(g&128){var u=e[b++]&63;if(192==(g&224))d+=String.fromCharCode((g&31)<<6|u);else{var X=e[b++]&63;g=224==
|
||||
(g&240)?(g&15)<<12|u<<6|X:(g&7)<<18|u<<12|X<<6|e[b++]&63;65536>g?d+=String.fromCharCode(g):(g-=65536,d+=String.fromCharCode(55296|g>>10,56320|g&1023))}}else d+=String.fromCharCode(g)}return d}function h(e,b){return e?p(ea,e,b):""}function A(){var e=ja.buffer;a.HEAP8=Y=new Int8Array(e);a.HEAP16=new Int16Array(e);a.HEAP32=ca=new Int32Array(e);a.HEAPU8=ea=new Uint8Array(e);a.HEAPU16=new Uint16Array(e);a.HEAPU32=V=new Uint32Array(e);a.HEAPF32=new Float32Array(e);a.HEAPF64=new Float64Array(e)}function f(e){if(a.onAbort)a.onAbort(e);
|
||||
e="Aborted("+e+")";da(e);wa=!0;e=new WebAssembly.RuntimeError(e+". Build with -sASSERTIONS for more info.");ka(e);throw e;}function q(e){try{if(e==P&&fa)return new Uint8Array(fa);if(ma)return ma(e);throw"both async and sync fetching of the wasm failed";}catch(b){f(b)}}function v(){if(!fa&&(xa||ha)){if("function"==typeof fetch&&!P.startsWith("file://"))return fetch(P,{credentials:"same-origin"}).then(function(e){if(!e.ok)throw"failed to load wasm binary file at '"+P+"'";return e.arrayBuffer()}).catch(function(){return q(P)});
|
||||
if(na)return new Promise(function(e,b){na(P,function(c){e(new Uint8Array(c))},b)})}return Promise.resolve().then(function(){return q(P)})}function z(e){for(;0<e.length;)e.shift()(a)}function O(e){this.excPtr=e;this.ptr=e-24;this.set_type=function(b){V[this.ptr+4>>2]=b};this.get_type=function(){return V[this.ptr+4>>2]};this.set_destructor=function(b){V[this.ptr+8>>2]=b};this.get_destructor=function(){return V[this.ptr+8>>2]};this.set_refcount=function(b){ca[this.ptr>>2]=b};this.set_caught=function(b){Y[this.ptr+
|
||||
12>>0]=b?1:0};this.get_caught=function(){return 0!=Y[this.ptr+12>>0]};this.set_rethrown=function(b){Y[this.ptr+13>>0]=b?1:0};this.get_rethrown=function(){return 0!=Y[this.ptr+13>>0]};this.init=function(b,c){this.set_adjusted_ptr(0);this.set_type(b);this.set_destructor(c);this.set_refcount(0);this.set_caught(!1);this.set_rethrown(!1)};this.add_ref=function(){ca[this.ptr>>2]+=1};this.release_ref=function(){var b=ca[this.ptr>>2];ca[this.ptr>>2]=b-1;return 1===b};this.set_adjusted_ptr=function(b){V[this.ptr+
|
||||
16>>2]=b};this.get_adjusted_ptr=function(){return V[this.ptr+16>>2]};this.get_exception_ptr=function(){if(ya(this.get_type()))return V[this.excPtr>>2];var b=this.get_adjusted_ptr();return 0!==b?b:this.excPtr}}function ba(){function e(){if(!la&&(la=!0,a.calledRun=!0,!wa)){za=!0;z(oa);Aa(a);if(a.onRuntimeInitialized)a.onRuntimeInitialized();if(a.postRun)for("function"==typeof a.postRun&&(a.postRun=[a.postRun]);a.postRun.length;)Ba.unshift(a.postRun.shift());z(Ba)}}if(!(0<aa)){if(a.preRun)for("function"==
|
||||
typeof a.preRun&&(a.preRun=[a.preRun]);a.preRun.length;)Ca.unshift(a.preRun.shift());z(Ca);0<aa||(a.setStatus?(a.setStatus("Running..."),setTimeout(function(){setTimeout(function(){a.setStatus("")},1);e()},1)):e())}}function t(){}function x(e){return(e||t).__cache__}function D(e,b){var c=x(b),d=c[e];if(d)return d;d=Object.create((b||t).prototype);d.ptr=e;return c[e]=d}function R(e){if("string"===typeof e){for(var b=0,c=0;c<e.length;++c){var d=e.charCodeAt(c);127>=d?b++:2047>=d?b+=2:55296<=d&&57343>=
|
||||
d?(b+=4,++c):b+=3}b=Array(b+1);c=0;d=b.length;if(0<d){d=c+d-1;for(var g=0;g<e.length;++g){var u=e.charCodeAt(g);if(55296<=u&&57343>=u){var X=e.charCodeAt(++g);u=65536+((u&1023)<<10)|X&1023}if(127>=u){if(c>=d)break;b[c++]=u}else{if(2047>=u){if(c+1>=d)break;b[c++]=192|u>>6}else{if(65535>=u){if(c+2>=d)break;b[c++]=224|u>>12}else{if(c+3>=d)break;b[c++]=240|u>>18;b[c++]=128|u>>12&63}b[c++]=128|u>>6&63}b[c++]=128|u&63}}b[c]=0}e=r.alloc(b,Y);r.copy(b,Y,e);return e}return e}function pa(e){if("object"===typeof e){var b=
|
||||
r.alloc(e,Y);r.copy(e,Y,b);return b}return e}function Z(){throw"cannot construct a VoidPtr, no constructor in IDL";}function S(){this.ptr=Da();x(S)[this.ptr]=this}function Q(){this.ptr=Ea();x(Q)[this.ptr]=this}function W(){this.ptr=Fa();x(W)[this.ptr]=this}function w(){this.ptr=Ga();x(w)[this.ptr]=this}function C(){this.ptr=Ha();x(C)[this.ptr]=this}function F(){this.ptr=Ia();x(F)[this.ptr]=this}function G(){this.ptr=Ja();x(G)[this.ptr]=this}function E(){this.ptr=Ka();x(E)[this.ptr]=this}function T(){this.ptr=
|
||||
La();x(T)[this.ptr]=this}function B(){throw"cannot construct a Status, no constructor in IDL";}function H(){this.ptr=Ma();x(H)[this.ptr]=this}function I(){this.ptr=Na();x(I)[this.ptr]=this}function J(){this.ptr=Oa();x(J)[this.ptr]=this}function K(){this.ptr=Pa();x(K)[this.ptr]=this}function L(){this.ptr=Qa();x(L)[this.ptr]=this}function M(){this.ptr=Ra();x(M)[this.ptr]=this}function N(){this.ptr=Sa();x(N)[this.ptr]=this}function y(){this.ptr=Ta();x(y)[this.ptr]=this}function m(){this.ptr=Ua();x(m)[this.ptr]=
|
||||
this}n=void 0===n?{}:n;var a="undefined"!=typeof n?n:{},Aa,ka;a.ready=new Promise(function(e,b){Aa=e;ka=b});var Va=!1,Wa=!1;a.onRuntimeInitialized=function(){Va=!0;if(Wa&&"function"===typeof a.onModuleLoaded)a.onModuleLoaded(a)};a.onModuleParsed=function(){Wa=!0;if(Va&&"function"===typeof a.onModuleLoaded)a.onModuleLoaded(a)};a.isVersionSupported=function(e){if("string"!==typeof e)return!1;e=e.split(".");return 2>e.length||3<e.length?!1:1==e[0]&&0<=e[1]&&5>=e[1]?!0:0!=e[0]||10<e[1]?!1:!0};var Xa=
|
||||
Object.assign({},a),xa="object"==typeof window,ha="function"==typeof importScripts,Ya="object"==typeof process&&"object"==typeof process.versions&&"string"==typeof process.versions.node,U="";if(Ya){var Za=require("fs"),qa=require("path");U=ha?qa.dirname(U)+"/":__dirname+"/";var $a=function(e,b){e=e.startsWith("file://")?new URL(e):qa.normalize(e);return Za.readFileSync(e,b?void 0:"utf8")};var ma=function(e){e=$a(e,!0);e.buffer||(e=new Uint8Array(e));return e};var na=function(e,b,c){e=e.startsWith("file://")?
|
||||
new URL(e):qa.normalize(e);Za.readFile(e,function(d,g){d?c(d):b(g.buffer)})};1<process.argv.length&&process.argv[1].replace(/\\/g,"/");process.argv.slice(2);a.inspect=function(){return"[Emscripten Module object]"}}else if(xa||ha)ha?U=self.location.href:"undefined"!=typeof document&&document.currentScript&&(U=document.currentScript.src),k&&(U=k),U=0!==U.indexOf("blob:")?U.substr(0,U.replace(/[?#].*/,"").lastIndexOf("/")+1):"",$a=function(e){var b=new XMLHttpRequest;b.open("GET",e,!1);b.send(null);
|
||||
return b.responseText},ha&&(ma=function(e){var b=new XMLHttpRequest;b.open("GET",e,!1);b.responseType="arraybuffer";b.send(null);return new Uint8Array(b.response)}),na=function(e,b,c){var d=new XMLHttpRequest;d.open("GET",e,!0);d.responseType="arraybuffer";d.onload=function(){200==d.status||0==d.status&&d.response?b(d.response):c()};d.onerror=c;d.send(null)};var ud=a.print||console.log.bind(console),da=a.printErr||console.warn.bind(console);Object.assign(a,Xa);Xa=null;var fa;a.wasmBinary&&(fa=a.wasmBinary);
|
||||
"object"!=typeof WebAssembly&&f("no native wasm support detected");var ja,wa=!1,va="undefined"!=typeof TextDecoder?new TextDecoder("utf8"):void 0,Y,ea,ca,V,Ca=[],oa=[],Ba=[],za=!1,aa=0,ra=null,ia=null;var P="draco_decoder.wasm";P.startsWith("data:application/octet-stream;base64,")||(P=l(P));var vd=0,wd=[null,[],[]],xd={b:function(e,b,c){(new O(e)).init(b,c);vd++;throw e;},a:function(){f("")},g:function(e,b,c){ea.copyWithin(e,b,b+c)},e:function(e){var b=ea.length;e>>>=0;if(2147483648<e)return!1;for(var c=
|
||||
1;4>=c;c*=2){var d=b*(1+.2/c);d=Math.min(d,e+100663296);var g=Math;d=Math.max(e,d);g=g.min.call(g,2147483648,d+(65536-d%65536)%65536);a:{d=ja.buffer;try{ja.grow(g-d.byteLength+65535>>>16);A();var u=1;break a}catch(X){}u=void 0}if(u)return!0}return!1},f:function(e){return 52},d:function(e,b,c,d,g){return 70},c:function(e,b,c,d){for(var g=0,u=0;u<c;u++){var X=V[b>>2],ab=V[b+4>>2];b+=8;for(var sa=0;sa<ab;sa++){var ta=ea[X+sa],ua=wd[e];0===ta||10===ta?((1===e?ud:da)(p(ua,0)),ua.length=0):ua.push(ta)}g+=
|
||||
ab}V[d>>2]=g;return 0}};(function(){function e(g,u){a.asm=g.exports;ja=a.asm.h;A();oa.unshift(a.asm.i);aa--;a.monitorRunDependencies&&a.monitorRunDependencies(aa);0==aa&&(null!==ra&&(clearInterval(ra),ra=null),ia&&(g=ia,ia=null,g()))}function b(g){e(g.instance)}function c(g){return v().then(function(u){return WebAssembly.instantiate(u,d)}).then(function(u){return u}).then(g,function(u){da("failed to asynchronously prepare wasm: "+u);f(u)})}var d={a:xd};aa++;a.monitorRunDependencies&&a.monitorRunDependencies(aa);
|
||||
if(a.instantiateWasm)try{return a.instantiateWasm(d,e)}catch(g){da("Module.instantiateWasm callback failed with error: "+g),ka(g)}(function(){return fa||"function"!=typeof WebAssembly.instantiateStreaming||P.startsWith("data:application/octet-stream;base64,")||P.startsWith("file://")||Ya||"function"!=typeof fetch?c(b):fetch(P,{credentials:"same-origin"}).then(function(g){return WebAssembly.instantiateStreaming(g,d).then(b,function(u){da("wasm streaming compile failed: "+u);da("falling back to ArrayBuffer instantiation");
|
||||
return c(b)})})})().catch(ka);return{}})();var bb=a._emscripten_bind_VoidPtr___destroy___0=function(){return(bb=a._emscripten_bind_VoidPtr___destroy___0=a.asm.k).apply(null,arguments)},Da=a._emscripten_bind_DecoderBuffer_DecoderBuffer_0=function(){return(Da=a._emscripten_bind_DecoderBuffer_DecoderBuffer_0=a.asm.l).apply(null,arguments)},cb=a._emscripten_bind_DecoderBuffer_Init_2=function(){return(cb=a._emscripten_bind_DecoderBuffer_Init_2=a.asm.m).apply(null,arguments)},db=a._emscripten_bind_DecoderBuffer___destroy___0=
|
||||
function(){return(db=a._emscripten_bind_DecoderBuffer___destroy___0=a.asm.n).apply(null,arguments)},Ea=a._emscripten_bind_AttributeTransformData_AttributeTransformData_0=function(){return(Ea=a._emscripten_bind_AttributeTransformData_AttributeTransformData_0=a.asm.o).apply(null,arguments)},eb=a._emscripten_bind_AttributeTransformData_transform_type_0=function(){return(eb=a._emscripten_bind_AttributeTransformData_transform_type_0=a.asm.p).apply(null,arguments)},fb=a._emscripten_bind_AttributeTransformData___destroy___0=
|
||||
function(){return(fb=a._emscripten_bind_AttributeTransformData___destroy___0=a.asm.q).apply(null,arguments)},Fa=a._emscripten_bind_GeometryAttribute_GeometryAttribute_0=function(){return(Fa=a._emscripten_bind_GeometryAttribute_GeometryAttribute_0=a.asm.r).apply(null,arguments)},gb=a._emscripten_bind_GeometryAttribute___destroy___0=function(){return(gb=a._emscripten_bind_GeometryAttribute___destroy___0=a.asm.s).apply(null,arguments)},Ga=a._emscripten_bind_PointAttribute_PointAttribute_0=function(){return(Ga=
|
||||
a._emscripten_bind_PointAttribute_PointAttribute_0=a.asm.t).apply(null,arguments)},hb=a._emscripten_bind_PointAttribute_size_0=function(){return(hb=a._emscripten_bind_PointAttribute_size_0=a.asm.u).apply(null,arguments)},ib=a._emscripten_bind_PointAttribute_GetAttributeTransformData_0=function(){return(ib=a._emscripten_bind_PointAttribute_GetAttributeTransformData_0=a.asm.v).apply(null,arguments)},jb=a._emscripten_bind_PointAttribute_attribute_type_0=function(){return(jb=a._emscripten_bind_PointAttribute_attribute_type_0=
|
||||
a.asm.w).apply(null,arguments)},kb=a._emscripten_bind_PointAttribute_data_type_0=function(){return(kb=a._emscripten_bind_PointAttribute_data_type_0=a.asm.x).apply(null,arguments)},lb=a._emscripten_bind_PointAttribute_num_components_0=function(){return(lb=a._emscripten_bind_PointAttribute_num_components_0=a.asm.y).apply(null,arguments)},mb=a._emscripten_bind_PointAttribute_normalized_0=function(){return(mb=a._emscripten_bind_PointAttribute_normalized_0=a.asm.z).apply(null,arguments)},nb=a._emscripten_bind_PointAttribute_byte_stride_0=
|
||||
function(){return(nb=a._emscripten_bind_PointAttribute_byte_stride_0=a.asm.A).apply(null,arguments)},ob=a._emscripten_bind_PointAttribute_byte_offset_0=function(){return(ob=a._emscripten_bind_PointAttribute_byte_offset_0=a.asm.B).apply(null,arguments)},pb=a._emscripten_bind_PointAttribute_unique_id_0=function(){return(pb=a._emscripten_bind_PointAttribute_unique_id_0=a.asm.C).apply(null,arguments)},qb=a._emscripten_bind_PointAttribute___destroy___0=function(){return(qb=a._emscripten_bind_PointAttribute___destroy___0=
|
||||
a.asm.D).apply(null,arguments)},Ha=a._emscripten_bind_AttributeQuantizationTransform_AttributeQuantizationTransform_0=function(){return(Ha=a._emscripten_bind_AttributeQuantizationTransform_AttributeQuantizationTransform_0=a.asm.E).apply(null,arguments)},rb=a._emscripten_bind_AttributeQuantizationTransform_InitFromAttribute_1=function(){return(rb=a._emscripten_bind_AttributeQuantizationTransform_InitFromAttribute_1=a.asm.F).apply(null,arguments)},sb=a._emscripten_bind_AttributeQuantizationTransform_quantization_bits_0=
|
||||
function(){return(sb=a._emscripten_bind_AttributeQuantizationTransform_quantization_bits_0=a.asm.G).apply(null,arguments)},tb=a._emscripten_bind_AttributeQuantizationTransform_min_value_1=function(){return(tb=a._emscripten_bind_AttributeQuantizationTransform_min_value_1=a.asm.H).apply(null,arguments)},ub=a._emscripten_bind_AttributeQuantizationTransform_range_0=function(){return(ub=a._emscripten_bind_AttributeQuantizationTransform_range_0=a.asm.I).apply(null,arguments)},vb=a._emscripten_bind_AttributeQuantizationTransform___destroy___0=
|
||||
function(){return(vb=a._emscripten_bind_AttributeQuantizationTransform___destroy___0=a.asm.J).apply(null,arguments)},Ia=a._emscripten_bind_AttributeOctahedronTransform_AttributeOctahedronTransform_0=function(){return(Ia=a._emscripten_bind_AttributeOctahedronTransform_AttributeOctahedronTransform_0=a.asm.K).apply(null,arguments)},wb=a._emscripten_bind_AttributeOctahedronTransform_InitFromAttribute_1=function(){return(wb=a._emscripten_bind_AttributeOctahedronTransform_InitFromAttribute_1=a.asm.L).apply(null,
|
||||
arguments)},xb=a._emscripten_bind_AttributeOctahedronTransform_quantization_bits_0=function(){return(xb=a._emscripten_bind_AttributeOctahedronTransform_quantization_bits_0=a.asm.M).apply(null,arguments)},yb=a._emscripten_bind_AttributeOctahedronTransform___destroy___0=function(){return(yb=a._emscripten_bind_AttributeOctahedronTransform___destroy___0=a.asm.N).apply(null,arguments)},Ja=a._emscripten_bind_PointCloud_PointCloud_0=function(){return(Ja=a._emscripten_bind_PointCloud_PointCloud_0=a.asm.O).apply(null,
|
||||
arguments)},zb=a._emscripten_bind_PointCloud_num_attributes_0=function(){return(zb=a._emscripten_bind_PointCloud_num_attributes_0=a.asm.P).apply(null,arguments)},Ab=a._emscripten_bind_PointCloud_num_points_0=function(){return(Ab=a._emscripten_bind_PointCloud_num_points_0=a.asm.Q).apply(null,arguments)},Bb=a._emscripten_bind_PointCloud___destroy___0=function(){return(Bb=a._emscripten_bind_PointCloud___destroy___0=a.asm.R).apply(null,arguments)},Ka=a._emscripten_bind_Mesh_Mesh_0=function(){return(Ka=
|
||||
a._emscripten_bind_Mesh_Mesh_0=a.asm.S).apply(null,arguments)},Cb=a._emscripten_bind_Mesh_num_faces_0=function(){return(Cb=a._emscripten_bind_Mesh_num_faces_0=a.asm.T).apply(null,arguments)},Db=a._emscripten_bind_Mesh_num_attributes_0=function(){return(Db=a._emscripten_bind_Mesh_num_attributes_0=a.asm.U).apply(null,arguments)},Eb=a._emscripten_bind_Mesh_num_points_0=function(){return(Eb=a._emscripten_bind_Mesh_num_points_0=a.asm.V).apply(null,arguments)},Fb=a._emscripten_bind_Mesh___destroy___0=function(){return(Fb=
|
||||
a._emscripten_bind_Mesh___destroy___0=a.asm.W).apply(null,arguments)},La=a._emscripten_bind_Metadata_Metadata_0=function(){return(La=a._emscripten_bind_Metadata_Metadata_0=a.asm.X).apply(null,arguments)},Gb=a._emscripten_bind_Metadata___destroy___0=function(){return(Gb=a._emscripten_bind_Metadata___destroy___0=a.asm.Y).apply(null,arguments)},Hb=a._emscripten_bind_Status_code_0=function(){return(Hb=a._emscripten_bind_Status_code_0=a.asm.Z).apply(null,arguments)},Ib=a._emscripten_bind_Status_ok_0=function(){return(Ib=
|
||||
a._emscripten_bind_Status_ok_0=a.asm._).apply(null,arguments)},Jb=a._emscripten_bind_Status_error_msg_0=function(){return(Jb=a._emscripten_bind_Status_error_msg_0=a.asm.$).apply(null,arguments)},Kb=a._emscripten_bind_Status___destroy___0=function(){return(Kb=a._emscripten_bind_Status___destroy___0=a.asm.aa).apply(null,arguments)},Ma=a._emscripten_bind_DracoFloat32Array_DracoFloat32Array_0=function(){return(Ma=a._emscripten_bind_DracoFloat32Array_DracoFloat32Array_0=a.asm.ba).apply(null,arguments)},
|
||||
Lb=a._emscripten_bind_DracoFloat32Array_GetValue_1=function(){return(Lb=a._emscripten_bind_DracoFloat32Array_GetValue_1=a.asm.ca).apply(null,arguments)},Mb=a._emscripten_bind_DracoFloat32Array_size_0=function(){return(Mb=a._emscripten_bind_DracoFloat32Array_size_0=a.asm.da).apply(null,arguments)},Nb=a._emscripten_bind_DracoFloat32Array___destroy___0=function(){return(Nb=a._emscripten_bind_DracoFloat32Array___destroy___0=a.asm.ea).apply(null,arguments)},Na=a._emscripten_bind_DracoInt8Array_DracoInt8Array_0=
|
||||
function(){return(Na=a._emscripten_bind_DracoInt8Array_DracoInt8Array_0=a.asm.fa).apply(null,arguments)},Ob=a._emscripten_bind_DracoInt8Array_GetValue_1=function(){return(Ob=a._emscripten_bind_DracoInt8Array_GetValue_1=a.asm.ga).apply(null,arguments)},Pb=a._emscripten_bind_DracoInt8Array_size_0=function(){return(Pb=a._emscripten_bind_DracoInt8Array_size_0=a.asm.ha).apply(null,arguments)},Qb=a._emscripten_bind_DracoInt8Array___destroy___0=function(){return(Qb=a._emscripten_bind_DracoInt8Array___destroy___0=
|
||||
a.asm.ia).apply(null,arguments)},Oa=a._emscripten_bind_DracoUInt8Array_DracoUInt8Array_0=function(){return(Oa=a._emscripten_bind_DracoUInt8Array_DracoUInt8Array_0=a.asm.ja).apply(null,arguments)},Rb=a._emscripten_bind_DracoUInt8Array_GetValue_1=function(){return(Rb=a._emscripten_bind_DracoUInt8Array_GetValue_1=a.asm.ka).apply(null,arguments)},Sb=a._emscripten_bind_DracoUInt8Array_size_0=function(){return(Sb=a._emscripten_bind_DracoUInt8Array_size_0=a.asm.la).apply(null,arguments)},Tb=a._emscripten_bind_DracoUInt8Array___destroy___0=
|
||||
function(){return(Tb=a._emscripten_bind_DracoUInt8Array___destroy___0=a.asm.ma).apply(null,arguments)},Pa=a._emscripten_bind_DracoInt16Array_DracoInt16Array_0=function(){return(Pa=a._emscripten_bind_DracoInt16Array_DracoInt16Array_0=a.asm.na).apply(null,arguments)},Ub=a._emscripten_bind_DracoInt16Array_GetValue_1=function(){return(Ub=a._emscripten_bind_DracoInt16Array_GetValue_1=a.asm.oa).apply(null,arguments)},Vb=a._emscripten_bind_DracoInt16Array_size_0=function(){return(Vb=a._emscripten_bind_DracoInt16Array_size_0=
|
||||
a.asm.pa).apply(null,arguments)},Wb=a._emscripten_bind_DracoInt16Array___destroy___0=function(){return(Wb=a._emscripten_bind_DracoInt16Array___destroy___0=a.asm.qa).apply(null,arguments)},Qa=a._emscripten_bind_DracoUInt16Array_DracoUInt16Array_0=function(){return(Qa=a._emscripten_bind_DracoUInt16Array_DracoUInt16Array_0=a.asm.ra).apply(null,arguments)},Xb=a._emscripten_bind_DracoUInt16Array_GetValue_1=function(){return(Xb=a._emscripten_bind_DracoUInt16Array_GetValue_1=a.asm.sa).apply(null,arguments)},
|
||||
Yb=a._emscripten_bind_DracoUInt16Array_size_0=function(){return(Yb=a._emscripten_bind_DracoUInt16Array_size_0=a.asm.ta).apply(null,arguments)},Zb=a._emscripten_bind_DracoUInt16Array___destroy___0=function(){return(Zb=a._emscripten_bind_DracoUInt16Array___destroy___0=a.asm.ua).apply(null,arguments)},Ra=a._emscripten_bind_DracoInt32Array_DracoInt32Array_0=function(){return(Ra=a._emscripten_bind_DracoInt32Array_DracoInt32Array_0=a.asm.va).apply(null,arguments)},$b=a._emscripten_bind_DracoInt32Array_GetValue_1=
|
||||
function(){return($b=a._emscripten_bind_DracoInt32Array_GetValue_1=a.asm.wa).apply(null,arguments)},ac=a._emscripten_bind_DracoInt32Array_size_0=function(){return(ac=a._emscripten_bind_DracoInt32Array_size_0=a.asm.xa).apply(null,arguments)},bc=a._emscripten_bind_DracoInt32Array___destroy___0=function(){return(bc=a._emscripten_bind_DracoInt32Array___destroy___0=a.asm.ya).apply(null,arguments)},Sa=a._emscripten_bind_DracoUInt32Array_DracoUInt32Array_0=function(){return(Sa=a._emscripten_bind_DracoUInt32Array_DracoUInt32Array_0=
|
||||
a.asm.za).apply(null,arguments)},cc=a._emscripten_bind_DracoUInt32Array_GetValue_1=function(){return(cc=a._emscripten_bind_DracoUInt32Array_GetValue_1=a.asm.Aa).apply(null,arguments)},dc=a._emscripten_bind_DracoUInt32Array_size_0=function(){return(dc=a._emscripten_bind_DracoUInt32Array_size_0=a.asm.Ba).apply(null,arguments)},ec=a._emscripten_bind_DracoUInt32Array___destroy___0=function(){return(ec=a._emscripten_bind_DracoUInt32Array___destroy___0=a.asm.Ca).apply(null,arguments)},Ta=a._emscripten_bind_MetadataQuerier_MetadataQuerier_0=
|
||||
function(){return(Ta=a._emscripten_bind_MetadataQuerier_MetadataQuerier_0=a.asm.Da).apply(null,arguments)},fc=a._emscripten_bind_MetadataQuerier_HasEntry_2=function(){return(fc=a._emscripten_bind_MetadataQuerier_HasEntry_2=a.asm.Ea).apply(null,arguments)},gc=a._emscripten_bind_MetadataQuerier_GetIntEntry_2=function(){return(gc=a._emscripten_bind_MetadataQuerier_GetIntEntry_2=a.asm.Fa).apply(null,arguments)},hc=a._emscripten_bind_MetadataQuerier_GetIntEntryArray_3=function(){return(hc=a._emscripten_bind_MetadataQuerier_GetIntEntryArray_3=
|
||||
a.asm.Ga).apply(null,arguments)},ic=a._emscripten_bind_MetadataQuerier_GetDoubleEntry_2=function(){return(ic=a._emscripten_bind_MetadataQuerier_GetDoubleEntry_2=a.asm.Ha).apply(null,arguments)},jc=a._emscripten_bind_MetadataQuerier_GetStringEntry_2=function(){return(jc=a._emscripten_bind_MetadataQuerier_GetStringEntry_2=a.asm.Ia).apply(null,arguments)},kc=a._emscripten_bind_MetadataQuerier_NumEntries_1=function(){return(kc=a._emscripten_bind_MetadataQuerier_NumEntries_1=a.asm.Ja).apply(null,arguments)},
|
||||
lc=a._emscripten_bind_MetadataQuerier_GetEntryName_2=function(){return(lc=a._emscripten_bind_MetadataQuerier_GetEntryName_2=a.asm.Ka).apply(null,arguments)},mc=a._emscripten_bind_MetadataQuerier___destroy___0=function(){return(mc=a._emscripten_bind_MetadataQuerier___destroy___0=a.asm.La).apply(null,arguments)},Ua=a._emscripten_bind_Decoder_Decoder_0=function(){return(Ua=a._emscripten_bind_Decoder_Decoder_0=a.asm.Ma).apply(null,arguments)},nc=a._emscripten_bind_Decoder_DecodeArrayToPointCloud_3=function(){return(nc=
|
||||
a._emscripten_bind_Decoder_DecodeArrayToPointCloud_3=a.asm.Na).apply(null,arguments)},oc=a._emscripten_bind_Decoder_DecodeArrayToMesh_3=function(){return(oc=a._emscripten_bind_Decoder_DecodeArrayToMesh_3=a.asm.Oa).apply(null,arguments)},pc=a._emscripten_bind_Decoder_GetAttributeId_2=function(){return(pc=a._emscripten_bind_Decoder_GetAttributeId_2=a.asm.Pa).apply(null,arguments)},qc=a._emscripten_bind_Decoder_GetAttributeIdByName_2=function(){return(qc=a._emscripten_bind_Decoder_GetAttributeIdByName_2=
|
||||
a.asm.Qa).apply(null,arguments)},rc=a._emscripten_bind_Decoder_GetAttributeIdByMetadataEntry_3=function(){return(rc=a._emscripten_bind_Decoder_GetAttributeIdByMetadataEntry_3=a.asm.Ra).apply(null,arguments)},sc=a._emscripten_bind_Decoder_GetAttribute_2=function(){return(sc=a._emscripten_bind_Decoder_GetAttribute_2=a.asm.Sa).apply(null,arguments)},tc=a._emscripten_bind_Decoder_GetAttributeByUniqueId_2=function(){return(tc=a._emscripten_bind_Decoder_GetAttributeByUniqueId_2=a.asm.Ta).apply(null,arguments)},
|
||||
uc=a._emscripten_bind_Decoder_GetMetadata_1=function(){return(uc=a._emscripten_bind_Decoder_GetMetadata_1=a.asm.Ua).apply(null,arguments)},vc=a._emscripten_bind_Decoder_GetAttributeMetadata_2=function(){return(vc=a._emscripten_bind_Decoder_GetAttributeMetadata_2=a.asm.Va).apply(null,arguments)},wc=a._emscripten_bind_Decoder_GetFaceFromMesh_3=function(){return(wc=a._emscripten_bind_Decoder_GetFaceFromMesh_3=a.asm.Wa).apply(null,arguments)},xc=a._emscripten_bind_Decoder_GetTriangleStripsFromMesh_2=
|
||||
function(){return(xc=a._emscripten_bind_Decoder_GetTriangleStripsFromMesh_2=a.asm.Xa).apply(null,arguments)},yc=a._emscripten_bind_Decoder_GetTrianglesUInt16Array_3=function(){return(yc=a._emscripten_bind_Decoder_GetTrianglesUInt16Array_3=a.asm.Ya).apply(null,arguments)},zc=a._emscripten_bind_Decoder_GetTrianglesUInt32Array_3=function(){return(zc=a._emscripten_bind_Decoder_GetTrianglesUInt32Array_3=a.asm.Za).apply(null,arguments)},Ac=a._emscripten_bind_Decoder_GetAttributeFloat_3=function(){return(Ac=
|
||||
a._emscripten_bind_Decoder_GetAttributeFloat_3=a.asm._a).apply(null,arguments)},Bc=a._emscripten_bind_Decoder_GetAttributeFloatForAllPoints_3=function(){return(Bc=a._emscripten_bind_Decoder_GetAttributeFloatForAllPoints_3=a.asm.$a).apply(null,arguments)},Cc=a._emscripten_bind_Decoder_GetAttributeIntForAllPoints_3=function(){return(Cc=a._emscripten_bind_Decoder_GetAttributeIntForAllPoints_3=a.asm.ab).apply(null,arguments)},Dc=a._emscripten_bind_Decoder_GetAttributeInt8ForAllPoints_3=function(){return(Dc=
|
||||
a._emscripten_bind_Decoder_GetAttributeInt8ForAllPoints_3=a.asm.bb).apply(null,arguments)},Ec=a._emscripten_bind_Decoder_GetAttributeUInt8ForAllPoints_3=function(){return(Ec=a._emscripten_bind_Decoder_GetAttributeUInt8ForAllPoints_3=a.asm.cb).apply(null,arguments)},Fc=a._emscripten_bind_Decoder_GetAttributeInt16ForAllPoints_3=function(){return(Fc=a._emscripten_bind_Decoder_GetAttributeInt16ForAllPoints_3=a.asm.db).apply(null,arguments)},Gc=a._emscripten_bind_Decoder_GetAttributeUInt16ForAllPoints_3=
|
||||
function(){return(Gc=a._emscripten_bind_Decoder_GetAttributeUInt16ForAllPoints_3=a.asm.eb).apply(null,arguments)},Hc=a._emscripten_bind_Decoder_GetAttributeInt32ForAllPoints_3=function(){return(Hc=a._emscripten_bind_Decoder_GetAttributeInt32ForAllPoints_3=a.asm.fb).apply(null,arguments)},Ic=a._emscripten_bind_Decoder_GetAttributeUInt32ForAllPoints_3=function(){return(Ic=a._emscripten_bind_Decoder_GetAttributeUInt32ForAllPoints_3=a.asm.gb).apply(null,arguments)},Jc=a._emscripten_bind_Decoder_GetAttributeDataArrayForAllPoints_5=
|
||||
function(){return(Jc=a._emscripten_bind_Decoder_GetAttributeDataArrayForAllPoints_5=a.asm.hb).apply(null,arguments)},Kc=a._emscripten_bind_Decoder_SkipAttributeTransform_1=function(){return(Kc=a._emscripten_bind_Decoder_SkipAttributeTransform_1=a.asm.ib).apply(null,arguments)},Lc=a._emscripten_bind_Decoder_GetEncodedGeometryType_Deprecated_1=function(){return(Lc=a._emscripten_bind_Decoder_GetEncodedGeometryType_Deprecated_1=a.asm.jb).apply(null,arguments)},Mc=a._emscripten_bind_Decoder_DecodeBufferToPointCloud_2=
|
||||
function(){return(Mc=a._emscripten_bind_Decoder_DecodeBufferToPointCloud_2=a.asm.kb).apply(null,arguments)},Nc=a._emscripten_bind_Decoder_DecodeBufferToMesh_2=function(){return(Nc=a._emscripten_bind_Decoder_DecodeBufferToMesh_2=a.asm.lb).apply(null,arguments)},Oc=a._emscripten_bind_Decoder___destroy___0=function(){return(Oc=a._emscripten_bind_Decoder___destroy___0=a.asm.mb).apply(null,arguments)},Pc=a._emscripten_enum_draco_AttributeTransformType_ATTRIBUTE_INVALID_TRANSFORM=function(){return(Pc=a._emscripten_enum_draco_AttributeTransformType_ATTRIBUTE_INVALID_TRANSFORM=
|
||||
a.asm.nb).apply(null,arguments)},Qc=a._emscripten_enum_draco_AttributeTransformType_ATTRIBUTE_NO_TRANSFORM=function(){return(Qc=a._emscripten_enum_draco_AttributeTransformType_ATTRIBUTE_NO_TRANSFORM=a.asm.ob).apply(null,arguments)},Rc=a._emscripten_enum_draco_AttributeTransformType_ATTRIBUTE_QUANTIZATION_TRANSFORM=function(){return(Rc=a._emscripten_enum_draco_AttributeTransformType_ATTRIBUTE_QUANTIZATION_TRANSFORM=a.asm.pb).apply(null,arguments)},Sc=a._emscripten_enum_draco_AttributeTransformType_ATTRIBUTE_OCTAHEDRON_TRANSFORM=
|
||||
function(){return(Sc=a._emscripten_enum_draco_AttributeTransformType_ATTRIBUTE_OCTAHEDRON_TRANSFORM=a.asm.qb).apply(null,arguments)},Tc=a._emscripten_enum_draco_GeometryAttribute_Type_INVALID=function(){return(Tc=a._emscripten_enum_draco_GeometryAttribute_Type_INVALID=a.asm.rb).apply(null,arguments)},Uc=a._emscripten_enum_draco_GeometryAttribute_Type_POSITION=function(){return(Uc=a._emscripten_enum_draco_GeometryAttribute_Type_POSITION=a.asm.sb).apply(null,arguments)},Vc=a._emscripten_enum_draco_GeometryAttribute_Type_NORMAL=
|
||||
function(){return(Vc=a._emscripten_enum_draco_GeometryAttribute_Type_NORMAL=a.asm.tb).apply(null,arguments)},Wc=a._emscripten_enum_draco_GeometryAttribute_Type_COLOR=function(){return(Wc=a._emscripten_enum_draco_GeometryAttribute_Type_COLOR=a.asm.ub).apply(null,arguments)},Xc=a._emscripten_enum_draco_GeometryAttribute_Type_TEX_COORD=function(){return(Xc=a._emscripten_enum_draco_GeometryAttribute_Type_TEX_COORD=a.asm.vb).apply(null,arguments)},Yc=a._emscripten_enum_draco_GeometryAttribute_Type_GENERIC=
|
||||
function(){return(Yc=a._emscripten_enum_draco_GeometryAttribute_Type_GENERIC=a.asm.wb).apply(null,arguments)},Zc=a._emscripten_enum_draco_EncodedGeometryType_INVALID_GEOMETRY_TYPE=function(){return(Zc=a._emscripten_enum_draco_EncodedGeometryType_INVALID_GEOMETRY_TYPE=a.asm.xb).apply(null,arguments)},$c=a._emscripten_enum_draco_EncodedGeometryType_POINT_CLOUD=function(){return($c=a._emscripten_enum_draco_EncodedGeometryType_POINT_CLOUD=a.asm.yb).apply(null,arguments)},ad=a._emscripten_enum_draco_EncodedGeometryType_TRIANGULAR_MESH=
|
||||
function(){return(ad=a._emscripten_enum_draco_EncodedGeometryType_TRIANGULAR_MESH=a.asm.zb).apply(null,arguments)},bd=a._emscripten_enum_draco_DataType_DT_INVALID=function(){return(bd=a._emscripten_enum_draco_DataType_DT_INVALID=a.asm.Ab).apply(null,arguments)},cd=a._emscripten_enum_draco_DataType_DT_INT8=function(){return(cd=a._emscripten_enum_draco_DataType_DT_INT8=a.asm.Bb).apply(null,arguments)},dd=a._emscripten_enum_draco_DataType_DT_UINT8=function(){return(dd=a._emscripten_enum_draco_DataType_DT_UINT8=
|
||||
a.asm.Cb).apply(null,arguments)},ed=a._emscripten_enum_draco_DataType_DT_INT16=function(){return(ed=a._emscripten_enum_draco_DataType_DT_INT16=a.asm.Db).apply(null,arguments)},fd=a._emscripten_enum_draco_DataType_DT_UINT16=function(){return(fd=a._emscripten_enum_draco_DataType_DT_UINT16=a.asm.Eb).apply(null,arguments)},gd=a._emscripten_enum_draco_DataType_DT_INT32=function(){return(gd=a._emscripten_enum_draco_DataType_DT_INT32=a.asm.Fb).apply(null,arguments)},hd=a._emscripten_enum_draco_DataType_DT_UINT32=
|
||||
function(){return(hd=a._emscripten_enum_draco_DataType_DT_UINT32=a.asm.Gb).apply(null,arguments)},id=a._emscripten_enum_draco_DataType_DT_INT64=function(){return(id=a._emscripten_enum_draco_DataType_DT_INT64=a.asm.Hb).apply(null,arguments)},jd=a._emscripten_enum_draco_DataType_DT_UINT64=function(){return(jd=a._emscripten_enum_draco_DataType_DT_UINT64=a.asm.Ib).apply(null,arguments)},kd=a._emscripten_enum_draco_DataType_DT_FLOAT32=function(){return(kd=a._emscripten_enum_draco_DataType_DT_FLOAT32=a.asm.Jb).apply(null,
|
||||
arguments)},ld=a._emscripten_enum_draco_DataType_DT_FLOAT64=function(){return(ld=a._emscripten_enum_draco_DataType_DT_FLOAT64=a.asm.Kb).apply(null,arguments)},md=a._emscripten_enum_draco_DataType_DT_BOOL=function(){return(md=a._emscripten_enum_draco_DataType_DT_BOOL=a.asm.Lb).apply(null,arguments)},nd=a._emscripten_enum_draco_DataType_DT_TYPES_COUNT=function(){return(nd=a._emscripten_enum_draco_DataType_DT_TYPES_COUNT=a.asm.Mb).apply(null,arguments)},od=a._emscripten_enum_draco_StatusCode_OK=function(){return(od=
|
||||
a._emscripten_enum_draco_StatusCode_OK=a.asm.Nb).apply(null,arguments)},pd=a._emscripten_enum_draco_StatusCode_DRACO_ERROR=function(){return(pd=a._emscripten_enum_draco_StatusCode_DRACO_ERROR=a.asm.Ob).apply(null,arguments)},qd=a._emscripten_enum_draco_StatusCode_IO_ERROR=function(){return(qd=a._emscripten_enum_draco_StatusCode_IO_ERROR=a.asm.Pb).apply(null,arguments)},rd=a._emscripten_enum_draco_StatusCode_INVALID_PARAMETER=function(){return(rd=a._emscripten_enum_draco_StatusCode_INVALID_PARAMETER=
|
||||
a.asm.Qb).apply(null,arguments)},sd=a._emscripten_enum_draco_StatusCode_UNSUPPORTED_VERSION=function(){return(sd=a._emscripten_enum_draco_StatusCode_UNSUPPORTED_VERSION=a.asm.Rb).apply(null,arguments)},td=a._emscripten_enum_draco_StatusCode_UNKNOWN_VERSION=function(){return(td=a._emscripten_enum_draco_StatusCode_UNKNOWN_VERSION=a.asm.Sb).apply(null,arguments)};a._malloc=function(){return(a._malloc=a.asm.Tb).apply(null,arguments)};a._free=function(){return(a._free=a.asm.Ub).apply(null,arguments)};
|
||||
var ya=function(){return(ya=a.asm.Vb).apply(null,arguments)};a.___start_em_js=15856;a.___stop_em_js=15954;var la;ia=function b(){la||ba();la||(ia=b)};if(a.preInit)for("function"==typeof a.preInit&&(a.preInit=[a.preInit]);0<a.preInit.length;)a.preInit.pop()();ba();t.prototype=Object.create(t.prototype);t.prototype.constructor=t;t.prototype.__class__=t;t.__cache__={};a.WrapperObject=t;a.getCache=x;a.wrapPointer=D;a.castObject=function(b,c){return D(b.ptr,c)};a.NULL=D(0);a.destroy=function(b){if(!b.__destroy__)throw"Error: Cannot destroy object. (Did you create it yourself?)";
|
||||
b.__destroy__();delete x(b.__class__)[b.ptr]};a.compare=function(b,c){return b.ptr===c.ptr};a.getPointer=function(b){return b.ptr};a.getClass=function(b){return b.__class__};var r={buffer:0,size:0,pos:0,temps:[],needed:0,prepare:function(){if(r.needed){for(var b=0;b<r.temps.length;b++)a._free(r.temps[b]);r.temps.length=0;a._free(r.buffer);r.buffer=0;r.size+=r.needed;r.needed=0}r.buffer||(r.size+=128,r.buffer=a._malloc(r.size),r.buffer||f(void 0));r.pos=0},alloc:function(b,c){r.buffer||f(void 0);b=
|
||||
b.length*c.BYTES_PER_ELEMENT;b=b+7&-8;r.pos+b>=r.size?(0<b||f(void 0),r.needed+=b,c=a._malloc(b),r.temps.push(c)):(c=r.buffer+r.pos,r.pos+=b);return c},copy:function(b,c,d){d>>>=0;switch(c.BYTES_PER_ELEMENT){case 2:d>>>=1;break;case 4:d>>>=2;break;case 8:d>>>=3}for(var g=0;g<b.length;g++)c[d+g]=b[g]}};Z.prototype=Object.create(t.prototype);Z.prototype.constructor=Z;Z.prototype.__class__=Z;Z.__cache__={};a.VoidPtr=Z;Z.prototype.__destroy__=Z.prototype.__destroy__=function(){bb(this.ptr)};S.prototype=
|
||||
Object.create(t.prototype);S.prototype.constructor=S;S.prototype.__class__=S;S.__cache__={};a.DecoderBuffer=S;S.prototype.Init=S.prototype.Init=function(b,c){var d=this.ptr;r.prepare();"object"==typeof b&&(b=pa(b));c&&"object"===typeof c&&(c=c.ptr);cb(d,b,c)};S.prototype.__destroy__=S.prototype.__destroy__=function(){db(this.ptr)};Q.prototype=Object.create(t.prototype);Q.prototype.constructor=Q;Q.prototype.__class__=Q;Q.__cache__={};a.AttributeTransformData=Q;Q.prototype.transform_type=Q.prototype.transform_type=
|
||||
function(){return eb(this.ptr)};Q.prototype.__destroy__=Q.prototype.__destroy__=function(){fb(this.ptr)};W.prototype=Object.create(t.prototype);W.prototype.constructor=W;W.prototype.__class__=W;W.__cache__={};a.GeometryAttribute=W;W.prototype.__destroy__=W.prototype.__destroy__=function(){gb(this.ptr)};w.prototype=Object.create(t.prototype);w.prototype.constructor=w;w.prototype.__class__=w;w.__cache__={};a.PointAttribute=w;w.prototype.size=w.prototype.size=function(){return hb(this.ptr)};w.prototype.GetAttributeTransformData=
|
||||
w.prototype.GetAttributeTransformData=function(){return D(ib(this.ptr),Q)};w.prototype.attribute_type=w.prototype.attribute_type=function(){return jb(this.ptr)};w.prototype.data_type=w.prototype.data_type=function(){return kb(this.ptr)};w.prototype.num_components=w.prototype.num_components=function(){return lb(this.ptr)};w.prototype.normalized=w.prototype.normalized=function(){return!!mb(this.ptr)};w.prototype.byte_stride=w.prototype.byte_stride=function(){return nb(this.ptr)};w.prototype.byte_offset=
|
||||
w.prototype.byte_offset=function(){return ob(this.ptr)};w.prototype.unique_id=w.prototype.unique_id=function(){return pb(this.ptr)};w.prototype.__destroy__=w.prototype.__destroy__=function(){qb(this.ptr)};C.prototype=Object.create(t.prototype);C.prototype.constructor=C;C.prototype.__class__=C;C.__cache__={};a.AttributeQuantizationTransform=C;C.prototype.InitFromAttribute=C.prototype.InitFromAttribute=function(b){var c=this.ptr;b&&"object"===typeof b&&(b=b.ptr);return!!rb(c,b)};C.prototype.quantization_bits=
|
||||
C.prototype.quantization_bits=function(){return sb(this.ptr)};C.prototype.min_value=C.prototype.min_value=function(b){var c=this.ptr;b&&"object"===typeof b&&(b=b.ptr);return tb(c,b)};C.prototype.range=C.prototype.range=function(){return ub(this.ptr)};C.prototype.__destroy__=C.prototype.__destroy__=function(){vb(this.ptr)};F.prototype=Object.create(t.prototype);F.prototype.constructor=F;F.prototype.__class__=F;F.__cache__={};a.AttributeOctahedronTransform=F;F.prototype.InitFromAttribute=F.prototype.InitFromAttribute=
|
||||
function(b){var c=this.ptr;b&&"object"===typeof b&&(b=b.ptr);return!!wb(c,b)};F.prototype.quantization_bits=F.prototype.quantization_bits=function(){return xb(this.ptr)};F.prototype.__destroy__=F.prototype.__destroy__=function(){yb(this.ptr)};G.prototype=Object.create(t.prototype);G.prototype.constructor=G;G.prototype.__class__=G;G.__cache__={};a.PointCloud=G;G.prototype.num_attributes=G.prototype.num_attributes=function(){return zb(this.ptr)};G.prototype.num_points=G.prototype.num_points=function(){return Ab(this.ptr)};
|
||||
G.prototype.__destroy__=G.prototype.__destroy__=function(){Bb(this.ptr)};E.prototype=Object.create(t.prototype);E.prototype.constructor=E;E.prototype.__class__=E;E.__cache__={};a.Mesh=E;E.prototype.num_faces=E.prototype.num_faces=function(){return Cb(this.ptr)};E.prototype.num_attributes=E.prototype.num_attributes=function(){return Db(this.ptr)};E.prototype.num_points=E.prototype.num_points=function(){return Eb(this.ptr)};E.prototype.__destroy__=E.prototype.__destroy__=function(){Fb(this.ptr)};T.prototype=
|
||||
Object.create(t.prototype);T.prototype.constructor=T;T.prototype.__class__=T;T.__cache__={};a.Metadata=T;T.prototype.__destroy__=T.prototype.__destroy__=function(){Gb(this.ptr)};B.prototype=Object.create(t.prototype);B.prototype.constructor=B;B.prototype.__class__=B;B.__cache__={};a.Status=B;B.prototype.code=B.prototype.code=function(){return Hb(this.ptr)};B.prototype.ok=B.prototype.ok=function(){return!!Ib(this.ptr)};B.prototype.error_msg=B.prototype.error_msg=function(){return h(Jb(this.ptr))};
|
||||
B.prototype.__destroy__=B.prototype.__destroy__=function(){Kb(this.ptr)};H.prototype=Object.create(t.prototype);H.prototype.constructor=H;H.prototype.__class__=H;H.__cache__={};a.DracoFloat32Array=H;H.prototype.GetValue=H.prototype.GetValue=function(b){var c=this.ptr;b&&"object"===typeof b&&(b=b.ptr);return Lb(c,b)};H.prototype.size=H.prototype.size=function(){return Mb(this.ptr)};H.prototype.__destroy__=H.prototype.__destroy__=function(){Nb(this.ptr)};I.prototype=Object.create(t.prototype);I.prototype.constructor=
|
||||
I;I.prototype.__class__=I;I.__cache__={};a.DracoInt8Array=I;I.prototype.GetValue=I.prototype.GetValue=function(b){var c=this.ptr;b&&"object"===typeof b&&(b=b.ptr);return Ob(c,b)};I.prototype.size=I.prototype.size=function(){return Pb(this.ptr)};I.prototype.__destroy__=I.prototype.__destroy__=function(){Qb(this.ptr)};J.prototype=Object.create(t.prototype);J.prototype.constructor=J;J.prototype.__class__=J;J.__cache__={};a.DracoUInt8Array=J;J.prototype.GetValue=J.prototype.GetValue=function(b){var c=
|
||||
this.ptr;b&&"object"===typeof b&&(b=b.ptr);return Rb(c,b)};J.prototype.size=J.prototype.size=function(){return Sb(this.ptr)};J.prototype.__destroy__=J.prototype.__destroy__=function(){Tb(this.ptr)};K.prototype=Object.create(t.prototype);K.prototype.constructor=K;K.prototype.__class__=K;K.__cache__={};a.DracoInt16Array=K;K.prototype.GetValue=K.prototype.GetValue=function(b){var c=this.ptr;b&&"object"===typeof b&&(b=b.ptr);return Ub(c,b)};K.prototype.size=K.prototype.size=function(){return Vb(this.ptr)};
|
||||
K.prototype.__destroy__=K.prototype.__destroy__=function(){Wb(this.ptr)};L.prototype=Object.create(t.prototype);L.prototype.constructor=L;L.prototype.__class__=L;L.__cache__={};a.DracoUInt16Array=L;L.prototype.GetValue=L.prototype.GetValue=function(b){var c=this.ptr;b&&"object"===typeof b&&(b=b.ptr);return Xb(c,b)};L.prototype.size=L.prototype.size=function(){return Yb(this.ptr)};L.prototype.__destroy__=L.prototype.__destroy__=function(){Zb(this.ptr)};M.prototype=Object.create(t.prototype);M.prototype.constructor=
|
||||
M;M.prototype.__class__=M;M.__cache__={};a.DracoInt32Array=M;M.prototype.GetValue=M.prototype.GetValue=function(b){var c=this.ptr;b&&"object"===typeof b&&(b=b.ptr);return $b(c,b)};M.prototype.size=M.prototype.size=function(){return ac(this.ptr)};M.prototype.__destroy__=M.prototype.__destroy__=function(){bc(this.ptr)};N.prototype=Object.create(t.prototype);N.prototype.constructor=N;N.prototype.__class__=N;N.__cache__={};a.DracoUInt32Array=N;N.prototype.GetValue=N.prototype.GetValue=function(b){var c=
|
||||
this.ptr;b&&"object"===typeof b&&(b=b.ptr);return cc(c,b)};N.prototype.size=N.prototype.size=function(){return dc(this.ptr)};N.prototype.__destroy__=N.prototype.__destroy__=function(){ec(this.ptr)};y.prototype=Object.create(t.prototype);y.prototype.constructor=y;y.prototype.__class__=y;y.__cache__={};a.MetadataQuerier=y;y.prototype.HasEntry=y.prototype.HasEntry=function(b,c){var d=this.ptr;r.prepare();b&&"object"===typeof b&&(b=b.ptr);c=c&&"object"===typeof c?c.ptr:R(c);return!!fc(d,b,c)};y.prototype.GetIntEntry=
|
||||
y.prototype.GetIntEntry=function(b,c){var d=this.ptr;r.prepare();b&&"object"===typeof b&&(b=b.ptr);c=c&&"object"===typeof c?c.ptr:R(c);return gc(d,b,c)};y.prototype.GetIntEntryArray=y.prototype.GetIntEntryArray=function(b,c,d){var g=this.ptr;r.prepare();b&&"object"===typeof b&&(b=b.ptr);c=c&&"object"===typeof c?c.ptr:R(c);d&&"object"===typeof d&&(d=d.ptr);hc(g,b,c,d)};y.prototype.GetDoubleEntry=y.prototype.GetDoubleEntry=function(b,c){var d=this.ptr;r.prepare();b&&"object"===typeof b&&(b=b.ptr);c=
|
||||
c&&"object"===typeof c?c.ptr:R(c);return ic(d,b,c)};y.prototype.GetStringEntry=y.prototype.GetStringEntry=function(b,c){var d=this.ptr;r.prepare();b&&"object"===typeof b&&(b=b.ptr);c=c&&"object"===typeof c?c.ptr:R(c);return h(jc(d,b,c))};y.prototype.NumEntries=y.prototype.NumEntries=function(b){var c=this.ptr;b&&"object"===typeof b&&(b=b.ptr);return kc(c,b)};y.prototype.GetEntryName=y.prototype.GetEntryName=function(b,c){var d=this.ptr;b&&"object"===typeof b&&(b=b.ptr);c&&"object"===typeof c&&(c=
|
||||
c.ptr);return h(lc(d,b,c))};y.prototype.__destroy__=y.prototype.__destroy__=function(){mc(this.ptr)};m.prototype=Object.create(t.prototype);m.prototype.constructor=m;m.prototype.__class__=m;m.__cache__={};a.Decoder=m;m.prototype.DecodeArrayToPointCloud=m.prototype.DecodeArrayToPointCloud=function(b,c,d){var g=this.ptr;r.prepare();"object"==typeof b&&(b=pa(b));c&&"object"===typeof c&&(c=c.ptr);d&&"object"===typeof d&&(d=d.ptr);return D(nc(g,b,c,d),B)};m.prototype.DecodeArrayToMesh=m.prototype.DecodeArrayToMesh=
|
||||
function(b,c,d){var g=this.ptr;r.prepare();"object"==typeof b&&(b=pa(b));c&&"object"===typeof c&&(c=c.ptr);d&&"object"===typeof d&&(d=d.ptr);return D(oc(g,b,c,d),B)};m.prototype.GetAttributeId=m.prototype.GetAttributeId=function(b,c){var d=this.ptr;b&&"object"===typeof b&&(b=b.ptr);c&&"object"===typeof c&&(c=c.ptr);return pc(d,b,c)};m.prototype.GetAttributeIdByName=m.prototype.GetAttributeIdByName=function(b,c){var d=this.ptr;r.prepare();b&&"object"===typeof b&&(b=b.ptr);c=c&&"object"===typeof c?
|
||||
c.ptr:R(c);return qc(d,b,c)};m.prototype.GetAttributeIdByMetadataEntry=m.prototype.GetAttributeIdByMetadataEntry=function(b,c,d){var g=this.ptr;r.prepare();b&&"object"===typeof b&&(b=b.ptr);c=c&&"object"===typeof c?c.ptr:R(c);d=d&&"object"===typeof d?d.ptr:R(d);return rc(g,b,c,d)};m.prototype.GetAttribute=m.prototype.GetAttribute=function(b,c){var d=this.ptr;b&&"object"===typeof b&&(b=b.ptr);c&&"object"===typeof c&&(c=c.ptr);return D(sc(d,b,c),w)};m.prototype.GetAttributeByUniqueId=m.prototype.GetAttributeByUniqueId=
|
||||
function(b,c){var d=this.ptr;b&&"object"===typeof b&&(b=b.ptr);c&&"object"===typeof c&&(c=c.ptr);return D(tc(d,b,c),w)};m.prototype.GetMetadata=m.prototype.GetMetadata=function(b){var c=this.ptr;b&&"object"===typeof b&&(b=b.ptr);return D(uc(c,b),T)};m.prototype.GetAttributeMetadata=m.prototype.GetAttributeMetadata=function(b,c){var d=this.ptr;b&&"object"===typeof b&&(b=b.ptr);c&&"object"===typeof c&&(c=c.ptr);return D(vc(d,b,c),T)};m.prototype.GetFaceFromMesh=m.prototype.GetFaceFromMesh=function(b,
|
||||
c,d){var g=this.ptr;b&&"object"===typeof b&&(b=b.ptr);c&&"object"===typeof c&&(c=c.ptr);d&&"object"===typeof d&&(d=d.ptr);return!!wc(g,b,c,d)};m.prototype.GetTriangleStripsFromMesh=m.prototype.GetTriangleStripsFromMesh=function(b,c){var d=this.ptr;b&&"object"===typeof b&&(b=b.ptr);c&&"object"===typeof c&&(c=c.ptr);return xc(d,b,c)};m.prototype.GetTrianglesUInt16Array=m.prototype.GetTrianglesUInt16Array=function(b,c,d){var g=this.ptr;b&&"object"===typeof b&&(b=b.ptr);c&&"object"===typeof c&&(c=c.ptr);
|
||||
d&&"object"===typeof d&&(d=d.ptr);return!!yc(g,b,c,d)};m.prototype.GetTrianglesUInt32Array=m.prototype.GetTrianglesUInt32Array=function(b,c,d){var g=this.ptr;b&&"object"===typeof b&&(b=b.ptr);c&&"object"===typeof c&&(c=c.ptr);d&&"object"===typeof d&&(d=d.ptr);return!!zc(g,b,c,d)};m.prototype.GetAttributeFloat=m.prototype.GetAttributeFloat=function(b,c,d){var g=this.ptr;b&&"object"===typeof b&&(b=b.ptr);c&&"object"===typeof c&&(c=c.ptr);d&&"object"===typeof d&&(d=d.ptr);return!!Ac(g,b,c,d)};m.prototype.GetAttributeFloatForAllPoints=
|
||||
m.prototype.GetAttributeFloatForAllPoints=function(b,c,d){var g=this.ptr;b&&"object"===typeof b&&(b=b.ptr);c&&"object"===typeof c&&(c=c.ptr);d&&"object"===typeof d&&(d=d.ptr);return!!Bc(g,b,c,d)};m.prototype.GetAttributeIntForAllPoints=m.prototype.GetAttributeIntForAllPoints=function(b,c,d){var g=this.ptr;b&&"object"===typeof b&&(b=b.ptr);c&&"object"===typeof c&&(c=c.ptr);d&&"object"===typeof d&&(d=d.ptr);return!!Cc(g,b,c,d)};m.prototype.GetAttributeInt8ForAllPoints=m.prototype.GetAttributeInt8ForAllPoints=
|
||||
function(b,c,d){var g=this.ptr;b&&"object"===typeof b&&(b=b.ptr);c&&"object"===typeof c&&(c=c.ptr);d&&"object"===typeof d&&(d=d.ptr);return!!Dc(g,b,c,d)};m.prototype.GetAttributeUInt8ForAllPoints=m.prototype.GetAttributeUInt8ForAllPoints=function(b,c,d){var g=this.ptr;b&&"object"===typeof b&&(b=b.ptr);c&&"object"===typeof c&&(c=c.ptr);d&&"object"===typeof d&&(d=d.ptr);return!!Ec(g,b,c,d)};m.prototype.GetAttributeInt16ForAllPoints=m.prototype.GetAttributeInt16ForAllPoints=function(b,c,d){var g=this.ptr;
|
||||
b&&"object"===typeof b&&(b=b.ptr);c&&"object"===typeof c&&(c=c.ptr);d&&"object"===typeof d&&(d=d.ptr);return!!Fc(g,b,c,d)};m.prototype.GetAttributeUInt16ForAllPoints=m.prototype.GetAttributeUInt16ForAllPoints=function(b,c,d){var g=this.ptr;b&&"object"===typeof b&&(b=b.ptr);c&&"object"===typeof c&&(c=c.ptr);d&&"object"===typeof d&&(d=d.ptr);return!!Gc(g,b,c,d)};m.prototype.GetAttributeInt32ForAllPoints=m.prototype.GetAttributeInt32ForAllPoints=function(b,c,d){var g=this.ptr;b&&"object"===typeof b&&
|
||||
(b=b.ptr);c&&"object"===typeof c&&(c=c.ptr);d&&"object"===typeof d&&(d=d.ptr);return!!Hc(g,b,c,d)};m.prototype.GetAttributeUInt32ForAllPoints=m.prototype.GetAttributeUInt32ForAllPoints=function(b,c,d){var g=this.ptr;b&&"object"===typeof b&&(b=b.ptr);c&&"object"===typeof c&&(c=c.ptr);d&&"object"===typeof d&&(d=d.ptr);return!!Ic(g,b,c,d)};m.prototype.GetAttributeDataArrayForAllPoints=m.prototype.GetAttributeDataArrayForAllPoints=function(b,c,d,g,u){var X=this.ptr;b&&"object"===typeof b&&(b=b.ptr);c&&
|
||||
"object"===typeof c&&(c=c.ptr);d&&"object"===typeof d&&(d=d.ptr);g&&"object"===typeof g&&(g=g.ptr);u&&"object"===typeof u&&(u=u.ptr);return!!Jc(X,b,c,d,g,u)};m.prototype.SkipAttributeTransform=m.prototype.SkipAttributeTransform=function(b){var c=this.ptr;b&&"object"===typeof b&&(b=b.ptr);Kc(c,b)};m.prototype.GetEncodedGeometryType_Deprecated=m.prototype.GetEncodedGeometryType_Deprecated=function(b){var c=this.ptr;b&&"object"===typeof b&&(b=b.ptr);return Lc(c,b)};m.prototype.DecodeBufferToPointCloud=
|
||||
m.prototype.DecodeBufferToPointCloud=function(b,c){var d=this.ptr;b&&"object"===typeof b&&(b=b.ptr);c&&"object"===typeof c&&(c=c.ptr);return D(Mc(d,b,c),B)};m.prototype.DecodeBufferToMesh=m.prototype.DecodeBufferToMesh=function(b,c){var d=this.ptr;b&&"object"===typeof b&&(b=b.ptr);c&&"object"===typeof c&&(c=c.ptr);return D(Nc(d,b,c),B)};m.prototype.__destroy__=m.prototype.__destroy__=function(){Oc(this.ptr)};(function(){function b(){a.ATTRIBUTE_INVALID_TRANSFORM=Pc();a.ATTRIBUTE_NO_TRANSFORM=Qc();
|
||||
a.ATTRIBUTE_QUANTIZATION_TRANSFORM=Rc();a.ATTRIBUTE_OCTAHEDRON_TRANSFORM=Sc();a.INVALID=Tc();a.POSITION=Uc();a.NORMAL=Vc();a.COLOR=Wc();a.TEX_COORD=Xc();a.GENERIC=Yc();a.INVALID_GEOMETRY_TYPE=Zc();a.POINT_CLOUD=$c();a.TRIANGULAR_MESH=ad();a.DT_INVALID=bd();a.DT_INT8=cd();a.DT_UINT8=dd();a.DT_INT16=ed();a.DT_UINT16=fd();a.DT_INT32=gd();a.DT_UINT32=hd();a.DT_INT64=id();a.DT_UINT64=jd();a.DT_FLOAT32=kd();a.DT_FLOAT64=ld();a.DT_BOOL=md();a.DT_TYPES_COUNT=nd();a.OK=od();a.DRACO_ERROR=pd();a.IO_ERROR=qd();
|
||||
a.INVALID_PARAMETER=rd();a.UNSUPPORTED_VERSION=sd();a.UNKNOWN_VERSION=td()}za?b():oa.unshift(b)})();if("function"===typeof a.onModuleParsed)a.onModuleParsed();a.Decoder.prototype.GetEncodedGeometryType=function(b){if(b.__class__&&b.__class__===a.DecoderBuffer)return a.Decoder.prototype.GetEncodedGeometryType_Deprecated(b);if(8>b.byteLength)return a.INVALID_GEOMETRY_TYPE;switch(b[7]){case 0:return a.POINT_CLOUD;case 1:return a.TRIANGULAR_MESH;default:return a.INVALID_GEOMETRY_TYPE}};return n.ready}}();
|
||||
"object"===typeof exports&&"object"===typeof module?module.exports=DracoDecoderModule:"function"===typeof define&&define.amd?define([],function(){return DracoDecoderModule}):"object"===typeof exports&&(exports.DracoDecoderModule=DracoDecoderModule);
|
||||
33
public/draco/gltf/draco_decoder.js
Normal file
BIN
public/draco/gltf/draco_decoder.wasm
Normal file
33
public/draco/gltf/draco_encoder.js
Executable file
116
public/draco/gltf/draco_wasm_wrapper.js
Normal file
@@ -0,0 +1,116 @@
|
||||
var $jscomp=$jscomp||{};$jscomp.scope={};$jscomp.arrayIteratorImpl=function(h){var n=0;return function(){return n<h.length?{done:!1,value:h[n++]}:{done:!0}}};$jscomp.arrayIterator=function(h){return{next:$jscomp.arrayIteratorImpl(h)}};$jscomp.makeIterator=function(h){var n="undefined"!=typeof Symbol&&Symbol.iterator&&h[Symbol.iterator];return n?n.call(h):$jscomp.arrayIterator(h)};$jscomp.ASSUME_ES5=!1;$jscomp.ASSUME_NO_NATIVE_MAP=!1;$jscomp.ASSUME_NO_NATIVE_SET=!1;$jscomp.SIMPLE_FROUND_POLYFILL=!1;
|
||||
$jscomp.ISOLATE_POLYFILLS=!1;$jscomp.FORCE_POLYFILL_PROMISE=!1;$jscomp.FORCE_POLYFILL_PROMISE_WHEN_NO_UNHANDLED_REJECTION=!1;$jscomp.getGlobal=function(h){h=["object"==typeof globalThis&&globalThis,h,"object"==typeof window&&window,"object"==typeof self&&self,"object"==typeof global&&global];for(var n=0;n<h.length;++n){var k=h[n];if(k&&k.Math==Math)return k}throw Error("Cannot find global object");};$jscomp.global=$jscomp.getGlobal(this);
|
||||
$jscomp.defineProperty=$jscomp.ASSUME_ES5||"function"==typeof Object.defineProperties?Object.defineProperty:function(h,n,k){if(h==Array.prototype||h==Object.prototype)return h;h[n]=k.value;return h};$jscomp.IS_SYMBOL_NATIVE="function"===typeof Symbol&&"symbol"===typeof Symbol("x");$jscomp.TRUST_ES6_POLYFILLS=!$jscomp.ISOLATE_POLYFILLS||$jscomp.IS_SYMBOL_NATIVE;$jscomp.polyfills={};$jscomp.propertyToPolyfillSymbol={};$jscomp.POLYFILL_PREFIX="$jscp$";
|
||||
var $jscomp$lookupPolyfilledValue=function(h,n){var k=$jscomp.propertyToPolyfillSymbol[n];if(null==k)return h[n];k=h[k];return void 0!==k?k:h[n]};$jscomp.polyfill=function(h,n,k,p){n&&($jscomp.ISOLATE_POLYFILLS?$jscomp.polyfillIsolated(h,n,k,p):$jscomp.polyfillUnisolated(h,n,k,p))};
|
||||
$jscomp.polyfillUnisolated=function(h,n,k,p){k=$jscomp.global;h=h.split(".");for(p=0;p<h.length-1;p++){var l=h[p];if(!(l in k))return;k=k[l]}h=h[h.length-1];p=k[h];n=n(p);n!=p&&null!=n&&$jscomp.defineProperty(k,h,{configurable:!0,writable:!0,value:n})};
|
||||
$jscomp.polyfillIsolated=function(h,n,k,p){var l=h.split(".");h=1===l.length;p=l[0];p=!h&&p in $jscomp.polyfills?$jscomp.polyfills:$jscomp.global;for(var y=0;y<l.length-1;y++){var f=l[y];if(!(f in p))return;p=p[f]}l=l[l.length-1];k=$jscomp.IS_SYMBOL_NATIVE&&"es6"===k?p[l]:null;n=n(k);null!=n&&(h?$jscomp.defineProperty($jscomp.polyfills,l,{configurable:!0,writable:!0,value:n}):n!==k&&(void 0===$jscomp.propertyToPolyfillSymbol[l]&&(k=1E9*Math.random()>>>0,$jscomp.propertyToPolyfillSymbol[l]=$jscomp.IS_SYMBOL_NATIVE?
|
||||
$jscomp.global.Symbol(l):$jscomp.POLYFILL_PREFIX+k+"$"+l),$jscomp.defineProperty(p,$jscomp.propertyToPolyfillSymbol[l],{configurable:!0,writable:!0,value:n})))};
|
||||
$jscomp.polyfill("Promise",function(h){function n(){this.batch_=null}function k(f){return f instanceof l?f:new l(function(q,u){q(f)})}if(h&&(!($jscomp.FORCE_POLYFILL_PROMISE||$jscomp.FORCE_POLYFILL_PROMISE_WHEN_NO_UNHANDLED_REJECTION&&"undefined"===typeof $jscomp.global.PromiseRejectionEvent)||!$jscomp.global.Promise||-1===$jscomp.global.Promise.toString().indexOf("[native code]")))return h;n.prototype.asyncExecute=function(f){if(null==this.batch_){this.batch_=[];var q=this;this.asyncExecuteFunction(function(){q.executeBatch_()})}this.batch_.push(f)};
|
||||
var p=$jscomp.global.setTimeout;n.prototype.asyncExecuteFunction=function(f){p(f,0)};n.prototype.executeBatch_=function(){for(;this.batch_&&this.batch_.length;){var f=this.batch_;this.batch_=[];for(var q=0;q<f.length;++q){var u=f[q];f[q]=null;try{u()}catch(A){this.asyncThrow_(A)}}}this.batch_=null};n.prototype.asyncThrow_=function(f){this.asyncExecuteFunction(function(){throw f;})};var l=function(f){this.state_=0;this.result_=void 0;this.onSettledCallbacks_=[];this.isRejectionHandled_=!1;var q=this.createResolveAndReject_();
|
||||
try{f(q.resolve,q.reject)}catch(u){q.reject(u)}};l.prototype.createResolveAndReject_=function(){function f(A){return function(F){u||(u=!0,A.call(q,F))}}var q=this,u=!1;return{resolve:f(this.resolveTo_),reject:f(this.reject_)}};l.prototype.resolveTo_=function(f){if(f===this)this.reject_(new TypeError("A Promise cannot resolve to itself"));else if(f instanceof l)this.settleSameAsPromise_(f);else{a:switch(typeof f){case "object":var q=null!=f;break a;case "function":q=!0;break a;default:q=!1}q?this.resolveToNonPromiseObj_(f):
|
||||
this.fulfill_(f)}};l.prototype.resolveToNonPromiseObj_=function(f){var q=void 0;try{q=f.then}catch(u){this.reject_(u);return}"function"==typeof q?this.settleSameAsThenable_(q,f):this.fulfill_(f)};l.prototype.reject_=function(f){this.settle_(2,f)};l.prototype.fulfill_=function(f){this.settle_(1,f)};l.prototype.settle_=function(f,q){if(0!=this.state_)throw Error("Cannot settle("+f+", "+q+"): Promise already settled in state"+this.state_);this.state_=f;this.result_=q;2===this.state_&&this.scheduleUnhandledRejectionCheck_();
|
||||
this.executeOnSettledCallbacks_()};l.prototype.scheduleUnhandledRejectionCheck_=function(){var f=this;p(function(){if(f.notifyUnhandledRejection_()){var q=$jscomp.global.console;"undefined"!==typeof q&&q.error(f.result_)}},1)};l.prototype.notifyUnhandledRejection_=function(){if(this.isRejectionHandled_)return!1;var f=$jscomp.global.CustomEvent,q=$jscomp.global.Event,u=$jscomp.global.dispatchEvent;if("undefined"===typeof u)return!0;"function"===typeof f?f=new f("unhandledrejection",{cancelable:!0}):
|
||||
"function"===typeof q?f=new q("unhandledrejection",{cancelable:!0}):(f=$jscomp.global.document.createEvent("CustomEvent"),f.initCustomEvent("unhandledrejection",!1,!0,f));f.promise=this;f.reason=this.result_;return u(f)};l.prototype.executeOnSettledCallbacks_=function(){if(null!=this.onSettledCallbacks_){for(var f=0;f<this.onSettledCallbacks_.length;++f)y.asyncExecute(this.onSettledCallbacks_[f]);this.onSettledCallbacks_=null}};var y=new n;l.prototype.settleSameAsPromise_=function(f){var q=this.createResolveAndReject_();
|
||||
f.callWhenSettled_(q.resolve,q.reject)};l.prototype.settleSameAsThenable_=function(f,q){var u=this.createResolveAndReject_();try{f.call(q,u.resolve,u.reject)}catch(A){u.reject(A)}};l.prototype.then=function(f,q){function u(w,B){return"function"==typeof w?function(R){try{A(w(R))}catch(Z){F(Z)}}:B}var A,F,v=new l(function(w,B){A=w;F=B});this.callWhenSettled_(u(f,A),u(q,F));return v};l.prototype.catch=function(f){return this.then(void 0,f)};l.prototype.callWhenSettled_=function(f,q){function u(){switch(A.state_){case 1:f(A.result_);
|
||||
break;case 2:q(A.result_);break;default:throw Error("Unexpected state: "+A.state_);}}var A=this;null==this.onSettledCallbacks_?y.asyncExecute(u):this.onSettledCallbacks_.push(u);this.isRejectionHandled_=!0};l.resolve=k;l.reject=function(f){return new l(function(q,u){u(f)})};l.race=function(f){return new l(function(q,u){for(var A=$jscomp.makeIterator(f),F=A.next();!F.done;F=A.next())k(F.value).callWhenSettled_(q,u)})};l.all=function(f){var q=$jscomp.makeIterator(f),u=q.next();return u.done?k([]):new l(function(A,
|
||||
F){function v(R){return function(Z){w[R]=Z;B--;0==B&&A(w)}}var w=[],B=0;do w.push(void 0),B++,k(u.value).callWhenSettled_(v(w.length-1),F),u=q.next();while(!u.done)})};return l},"es6","es3");$jscomp.owns=function(h,n){return Object.prototype.hasOwnProperty.call(h,n)};$jscomp.assign=$jscomp.TRUST_ES6_POLYFILLS&&"function"==typeof Object.assign?Object.assign:function(h,n){for(var k=1;k<arguments.length;k++){var p=arguments[k];if(p)for(var l in p)$jscomp.owns(p,l)&&(h[l]=p[l])}return h};
|
||||
$jscomp.polyfill("Object.assign",function(h){return h||$jscomp.assign},"es6","es3");$jscomp.checkStringArgs=function(h,n,k){if(null==h)throw new TypeError("The 'this' value for String.prototype."+k+" must not be null or undefined");if(n instanceof RegExp)throw new TypeError("First argument to String.prototype."+k+" must not be a regular expression");return h+""};
|
||||
$jscomp.polyfill("String.prototype.startsWith",function(h){return h?h:function(n,k){var p=$jscomp.checkStringArgs(this,n,"startsWith");n+="";var l=p.length,y=n.length;k=Math.max(0,Math.min(k|0,p.length));for(var f=0;f<y&&k<l;)if(p[k++]!=n[f++])return!1;return f>=y}},"es6","es3");
|
||||
$jscomp.polyfill("Array.prototype.copyWithin",function(h){function n(k){k=Number(k);return Infinity===k||-Infinity===k?k:k|0}return h?h:function(k,p,l){var y=this.length;k=n(k);p=n(p);l=void 0===l?y:n(l);k=0>k?Math.max(y+k,0):Math.min(k,y);p=0>p?Math.max(y+p,0):Math.min(p,y);l=0>l?Math.max(y+l,0):Math.min(l,y);if(k<p)for(;p<l;)p in this?this[k++]=this[p++]:(delete this[k++],p++);else for(l=Math.min(l,y+p-k),k+=l-p;l>p;)--l in this?this[--k]=this[l]:delete this[--k];return this}},"es6","es3");
|
||||
$jscomp.typedArrayCopyWithin=function(h){return h?h:Array.prototype.copyWithin};$jscomp.polyfill("Int8Array.prototype.copyWithin",$jscomp.typedArrayCopyWithin,"es6","es5");$jscomp.polyfill("Uint8Array.prototype.copyWithin",$jscomp.typedArrayCopyWithin,"es6","es5");$jscomp.polyfill("Uint8ClampedArray.prototype.copyWithin",$jscomp.typedArrayCopyWithin,"es6","es5");$jscomp.polyfill("Int16Array.prototype.copyWithin",$jscomp.typedArrayCopyWithin,"es6","es5");
|
||||
$jscomp.polyfill("Uint16Array.prototype.copyWithin",$jscomp.typedArrayCopyWithin,"es6","es5");$jscomp.polyfill("Int32Array.prototype.copyWithin",$jscomp.typedArrayCopyWithin,"es6","es5");$jscomp.polyfill("Uint32Array.prototype.copyWithin",$jscomp.typedArrayCopyWithin,"es6","es5");$jscomp.polyfill("Float32Array.prototype.copyWithin",$jscomp.typedArrayCopyWithin,"es6","es5");$jscomp.polyfill("Float64Array.prototype.copyWithin",$jscomp.typedArrayCopyWithin,"es6","es5");
|
||||
var DracoDecoderModule=function(){var h="undefined"!==typeof document&&document.currentScript?document.currentScript.src:void 0;"undefined"!==typeof __filename&&(h=h||__filename);return function(n){function k(e){return a.locateFile?a.locateFile(e,U):U+e}function p(e,b){if(e){var c=ia;var d=e+b;for(b=e;c[b]&&!(b>=d);)++b;if(16<b-e&&c.buffer&&ra)c=ra.decode(c.subarray(e,b));else{for(d="";e<b;){var g=c[e++];if(g&128){var t=c[e++]&63;if(192==(g&224))d+=String.fromCharCode((g&31)<<6|t);else{var aa=c[e++]&
|
||||
63;g=224==(g&240)?(g&15)<<12|t<<6|aa:(g&7)<<18|t<<12|aa<<6|c[e++]&63;65536>g?d+=String.fromCharCode(g):(g-=65536,d+=String.fromCharCode(55296|g>>10,56320|g&1023))}}else d+=String.fromCharCode(g)}c=d}}else c="";return c}function l(){var e=ja.buffer;a.HEAP8=W=new Int8Array(e);a.HEAP16=new Int16Array(e);a.HEAP32=ca=new Int32Array(e);a.HEAPU8=ia=new Uint8Array(e);a.HEAPU16=new Uint16Array(e);a.HEAPU32=Y=new Uint32Array(e);a.HEAPF32=new Float32Array(e);a.HEAPF64=new Float64Array(e)}function y(e){if(a.onAbort)a.onAbort(e);
|
||||
e="Aborted("+e+")";da(e);sa=!0;e=new WebAssembly.RuntimeError(e+". Build with -sASSERTIONS for more info.");ka(e);throw e;}function f(e){try{if(e==P&&ea)return new Uint8Array(ea);if(ma)return ma(e);throw"both async and sync fetching of the wasm failed";}catch(b){y(b)}}function q(){if(!ea&&(ta||fa)){if("function"==typeof fetch&&!P.startsWith("file://"))return fetch(P,{credentials:"same-origin"}).then(function(e){if(!e.ok)throw"failed to load wasm binary file at '"+P+"'";return e.arrayBuffer()}).catch(function(){return f(P)});
|
||||
if(na)return new Promise(function(e,b){na(P,function(c){e(new Uint8Array(c))},b)})}return Promise.resolve().then(function(){return f(P)})}function u(e){for(;0<e.length;)e.shift()(a)}function A(e){this.excPtr=e;this.ptr=e-24;this.set_type=function(b){Y[this.ptr+4>>2]=b};this.get_type=function(){return Y[this.ptr+4>>2]};this.set_destructor=function(b){Y[this.ptr+8>>2]=b};this.get_destructor=function(){return Y[this.ptr+8>>2]};this.set_refcount=function(b){ca[this.ptr>>2]=b};this.set_caught=function(b){W[this.ptr+
|
||||
12>>0]=b?1:0};this.get_caught=function(){return 0!=W[this.ptr+12>>0]};this.set_rethrown=function(b){W[this.ptr+13>>0]=b?1:0};this.get_rethrown=function(){return 0!=W[this.ptr+13>>0]};this.init=function(b,c){this.set_adjusted_ptr(0);this.set_type(b);this.set_destructor(c);this.set_refcount(0);this.set_caught(!1);this.set_rethrown(!1)};this.add_ref=function(){ca[this.ptr>>2]+=1};this.release_ref=function(){var b=ca[this.ptr>>2];ca[this.ptr>>2]=b-1;return 1===b};this.set_adjusted_ptr=function(b){Y[this.ptr+
|
||||
16>>2]=b};this.get_adjusted_ptr=function(){return Y[this.ptr+16>>2]};this.get_exception_ptr=function(){if(ua(this.get_type()))return Y[this.excPtr>>2];var b=this.get_adjusted_ptr();return 0!==b?b:this.excPtr}}function F(){function e(){if(!la&&(la=!0,a.calledRun=!0,!sa)){va=!0;u(oa);wa(a);if(a.onRuntimeInitialized)a.onRuntimeInitialized();if(a.postRun)for("function"==typeof a.postRun&&(a.postRun=[a.postRun]);a.postRun.length;)xa.unshift(a.postRun.shift());u(xa)}}if(!(0<ba)){if(a.preRun)for("function"==
|
||||
typeof a.preRun&&(a.preRun=[a.preRun]);a.preRun.length;)ya.unshift(a.preRun.shift());u(ya);0<ba||(a.setStatus?(a.setStatus("Running..."),setTimeout(function(){setTimeout(function(){a.setStatus("")},1);e()},1)):e())}}function v(){}function w(e){return(e||v).__cache__}function B(e,b){var c=w(b),d=c[e];if(d)return d;d=Object.create((b||v).prototype);d.ptr=e;return c[e]=d}function R(e){if("string"===typeof e){for(var b=0,c=0;c<e.length;++c){var d=e.charCodeAt(c);127>=d?b++:2047>=d?b+=2:55296<=d&&57343>=
|
||||
d?(b+=4,++c):b+=3}b=Array(b+1);c=0;d=b.length;if(0<d){d=c+d-1;for(var g=0;g<e.length;++g){var t=e.charCodeAt(g);if(55296<=t&&57343>=t){var aa=e.charCodeAt(++g);t=65536+((t&1023)<<10)|aa&1023}if(127>=t){if(c>=d)break;b[c++]=t}else{if(2047>=t){if(c+1>=d)break;b[c++]=192|t>>6}else{if(65535>=t){if(c+2>=d)break;b[c++]=224|t>>12}else{if(c+3>=d)break;b[c++]=240|t>>18;b[c++]=128|t>>12&63}b[c++]=128|t>>6&63}b[c++]=128|t&63}}b[c]=0}e=r.alloc(b,W);r.copy(b,W,e);return e}return e}function Z(e){if("object"===
|
||||
typeof e){var b=r.alloc(e,W);r.copy(e,W,b);return b}return e}function X(){throw"cannot construct a VoidPtr, no constructor in IDL";}function S(){this.ptr=za();w(S)[this.ptr]=this}function Q(){this.ptr=Aa();w(Q)[this.ptr]=this}function V(){this.ptr=Ba();w(V)[this.ptr]=this}function x(){this.ptr=Ca();w(x)[this.ptr]=this}function D(){this.ptr=Da();w(D)[this.ptr]=this}function G(){this.ptr=Ea();w(G)[this.ptr]=this}function H(){this.ptr=Fa();w(H)[this.ptr]=this}function E(){this.ptr=Ga();w(E)[this.ptr]=
|
||||
this}function T(){this.ptr=Ha();w(T)[this.ptr]=this}function C(){throw"cannot construct a Status, no constructor in IDL";}function I(){this.ptr=Ia();w(I)[this.ptr]=this}function J(){this.ptr=Ja();w(J)[this.ptr]=this}function K(){this.ptr=Ka();w(K)[this.ptr]=this}function L(){this.ptr=La();w(L)[this.ptr]=this}function M(){this.ptr=Ma();w(M)[this.ptr]=this}function N(){this.ptr=Na();w(N)[this.ptr]=this}function O(){this.ptr=Oa();w(O)[this.ptr]=this}function z(){this.ptr=Pa();w(z)[this.ptr]=this}function m(){this.ptr=
|
||||
Qa();w(m)[this.ptr]=this}n=void 0===n?{}:n;var a="undefined"!=typeof n?n:{},wa,ka;a.ready=new Promise(function(e,b){wa=e;ka=b});var Ra=!1,Sa=!1;a.onRuntimeInitialized=function(){Ra=!0;if(Sa&&"function"===typeof a.onModuleLoaded)a.onModuleLoaded(a)};a.onModuleParsed=function(){Sa=!0;if(Ra&&"function"===typeof a.onModuleLoaded)a.onModuleLoaded(a)};a.isVersionSupported=function(e){if("string"!==typeof e)return!1;e=e.split(".");return 2>e.length||3<e.length?!1:1==e[0]&&0<=e[1]&&5>=e[1]?!0:0!=e[0]||10<
|
||||
e[1]?!1:!0};var Ta=Object.assign({},a),ta="object"==typeof window,fa="function"==typeof importScripts,Ua="object"==typeof process&&"object"==typeof process.versions&&"string"==typeof process.versions.node,U="";if(Ua){var Va=require("fs"),pa=require("path");U=fa?pa.dirname(U)+"/":__dirname+"/";var Wa=function(e,b){e=e.startsWith("file://")?new URL(e):pa.normalize(e);return Va.readFileSync(e,b?void 0:"utf8")};var ma=function(e){e=Wa(e,!0);e.buffer||(e=new Uint8Array(e));return e};var na=function(e,
|
||||
b,c){e=e.startsWith("file://")?new URL(e):pa.normalize(e);Va.readFile(e,function(d,g){d?c(d):b(g.buffer)})};1<process.argv.length&&process.argv[1].replace(/\\/g,"/");process.argv.slice(2);a.inspect=function(){return"[Emscripten Module object]"}}else if(ta||fa)fa?U=self.location.href:"undefined"!=typeof document&&document.currentScript&&(U=document.currentScript.src),h&&(U=h),U=0!==U.indexOf("blob:")?U.substr(0,U.replace(/[?#].*/,"").lastIndexOf("/")+1):"",Wa=function(e){var b=new XMLHttpRequest;b.open("GET",
|
||||
e,!1);b.send(null);return b.responseText},fa&&(ma=function(e){var b=new XMLHttpRequest;b.open("GET",e,!1);b.responseType="arraybuffer";b.send(null);return new Uint8Array(b.response)}),na=function(e,b,c){var d=new XMLHttpRequest;d.open("GET",e,!0);d.responseType="arraybuffer";d.onload=function(){200==d.status||0==d.status&&d.response?b(d.response):c()};d.onerror=c;d.send(null)};a.print||console.log.bind(console);var da=a.printErr||console.warn.bind(console);Object.assign(a,Ta);Ta=null;var ea;a.wasmBinary&&
|
||||
(ea=a.wasmBinary);"object"!=typeof WebAssembly&&y("no native wasm support detected");var ja,sa=!1,ra="undefined"!=typeof TextDecoder?new TextDecoder("utf8"):void 0,W,ia,ca,Y,ya=[],oa=[],xa=[],va=!1,ba=0,qa=null,ha=null;var P="draco_decoder_gltf.wasm";P.startsWith("data:application/octet-stream;base64,")||(P=k(P));var pd=0,qd={b:function(e,b,c){(new A(e)).init(b,c);pd++;throw e;},a:function(){y("")},d:function(e,b,c){ia.copyWithin(e,b,b+c)},c:function(e){var b=ia.length;e>>>=0;if(2147483648<e)return!1;
|
||||
for(var c=1;4>=c;c*=2){var d=b*(1+.2/c);d=Math.min(d,e+100663296);var g=Math;d=Math.max(e,d);g=g.min.call(g,2147483648,d+(65536-d%65536)%65536);a:{d=ja.buffer;try{ja.grow(g-d.byteLength+65535>>>16);l();var t=1;break a}catch(aa){}t=void 0}if(t)return!0}return!1}};(function(){function e(g,t){a.asm=g.exports;ja=a.asm.e;l();oa.unshift(a.asm.f);ba--;a.monitorRunDependencies&&a.monitorRunDependencies(ba);0==ba&&(null!==qa&&(clearInterval(qa),qa=null),ha&&(g=ha,ha=null,g()))}function b(g){e(g.instance)}
|
||||
function c(g){return q().then(function(t){return WebAssembly.instantiate(t,d)}).then(function(t){return t}).then(g,function(t){da("failed to asynchronously prepare wasm: "+t);y(t)})}var d={a:qd};ba++;a.monitorRunDependencies&&a.monitorRunDependencies(ba);if(a.instantiateWasm)try{return a.instantiateWasm(d,e)}catch(g){da("Module.instantiateWasm callback failed with error: "+g),ka(g)}(function(){return ea||"function"!=typeof WebAssembly.instantiateStreaming||P.startsWith("data:application/octet-stream;base64,")||
|
||||
P.startsWith("file://")||Ua||"function"!=typeof fetch?c(b):fetch(P,{credentials:"same-origin"}).then(function(g){return WebAssembly.instantiateStreaming(g,d).then(b,function(t){da("wasm streaming compile failed: "+t);da("falling back to ArrayBuffer instantiation");return c(b)})})})().catch(ka);return{}})();var Xa=a._emscripten_bind_VoidPtr___destroy___0=function(){return(Xa=a._emscripten_bind_VoidPtr___destroy___0=a.asm.h).apply(null,arguments)},za=a._emscripten_bind_DecoderBuffer_DecoderBuffer_0=
|
||||
function(){return(za=a._emscripten_bind_DecoderBuffer_DecoderBuffer_0=a.asm.i).apply(null,arguments)},Ya=a._emscripten_bind_DecoderBuffer_Init_2=function(){return(Ya=a._emscripten_bind_DecoderBuffer_Init_2=a.asm.j).apply(null,arguments)},Za=a._emscripten_bind_DecoderBuffer___destroy___0=function(){return(Za=a._emscripten_bind_DecoderBuffer___destroy___0=a.asm.k).apply(null,arguments)},Aa=a._emscripten_bind_AttributeTransformData_AttributeTransformData_0=function(){return(Aa=a._emscripten_bind_AttributeTransformData_AttributeTransformData_0=
|
||||
a.asm.l).apply(null,arguments)},$a=a._emscripten_bind_AttributeTransformData_transform_type_0=function(){return($a=a._emscripten_bind_AttributeTransformData_transform_type_0=a.asm.m).apply(null,arguments)},ab=a._emscripten_bind_AttributeTransformData___destroy___0=function(){return(ab=a._emscripten_bind_AttributeTransformData___destroy___0=a.asm.n).apply(null,arguments)},Ba=a._emscripten_bind_GeometryAttribute_GeometryAttribute_0=function(){return(Ba=a._emscripten_bind_GeometryAttribute_GeometryAttribute_0=
|
||||
a.asm.o).apply(null,arguments)},bb=a._emscripten_bind_GeometryAttribute___destroy___0=function(){return(bb=a._emscripten_bind_GeometryAttribute___destroy___0=a.asm.p).apply(null,arguments)},Ca=a._emscripten_bind_PointAttribute_PointAttribute_0=function(){return(Ca=a._emscripten_bind_PointAttribute_PointAttribute_0=a.asm.q).apply(null,arguments)},cb=a._emscripten_bind_PointAttribute_size_0=function(){return(cb=a._emscripten_bind_PointAttribute_size_0=a.asm.r).apply(null,arguments)},db=a._emscripten_bind_PointAttribute_GetAttributeTransformData_0=
|
||||
function(){return(db=a._emscripten_bind_PointAttribute_GetAttributeTransformData_0=a.asm.s).apply(null,arguments)},eb=a._emscripten_bind_PointAttribute_attribute_type_0=function(){return(eb=a._emscripten_bind_PointAttribute_attribute_type_0=a.asm.t).apply(null,arguments)},fb=a._emscripten_bind_PointAttribute_data_type_0=function(){return(fb=a._emscripten_bind_PointAttribute_data_type_0=a.asm.u).apply(null,arguments)},gb=a._emscripten_bind_PointAttribute_num_components_0=function(){return(gb=a._emscripten_bind_PointAttribute_num_components_0=
|
||||
a.asm.v).apply(null,arguments)},hb=a._emscripten_bind_PointAttribute_normalized_0=function(){return(hb=a._emscripten_bind_PointAttribute_normalized_0=a.asm.w).apply(null,arguments)},ib=a._emscripten_bind_PointAttribute_byte_stride_0=function(){return(ib=a._emscripten_bind_PointAttribute_byte_stride_0=a.asm.x).apply(null,arguments)},jb=a._emscripten_bind_PointAttribute_byte_offset_0=function(){return(jb=a._emscripten_bind_PointAttribute_byte_offset_0=a.asm.y).apply(null,arguments)},kb=a._emscripten_bind_PointAttribute_unique_id_0=
|
||||
function(){return(kb=a._emscripten_bind_PointAttribute_unique_id_0=a.asm.z).apply(null,arguments)},lb=a._emscripten_bind_PointAttribute___destroy___0=function(){return(lb=a._emscripten_bind_PointAttribute___destroy___0=a.asm.A).apply(null,arguments)},Da=a._emscripten_bind_AttributeQuantizationTransform_AttributeQuantizationTransform_0=function(){return(Da=a._emscripten_bind_AttributeQuantizationTransform_AttributeQuantizationTransform_0=a.asm.B).apply(null,arguments)},mb=a._emscripten_bind_AttributeQuantizationTransform_InitFromAttribute_1=
|
||||
function(){return(mb=a._emscripten_bind_AttributeQuantizationTransform_InitFromAttribute_1=a.asm.C).apply(null,arguments)},nb=a._emscripten_bind_AttributeQuantizationTransform_quantization_bits_0=function(){return(nb=a._emscripten_bind_AttributeQuantizationTransform_quantization_bits_0=a.asm.D).apply(null,arguments)},ob=a._emscripten_bind_AttributeQuantizationTransform_min_value_1=function(){return(ob=a._emscripten_bind_AttributeQuantizationTransform_min_value_1=a.asm.E).apply(null,arguments)},pb=
|
||||
a._emscripten_bind_AttributeQuantizationTransform_range_0=function(){return(pb=a._emscripten_bind_AttributeQuantizationTransform_range_0=a.asm.F).apply(null,arguments)},qb=a._emscripten_bind_AttributeQuantizationTransform___destroy___0=function(){return(qb=a._emscripten_bind_AttributeQuantizationTransform___destroy___0=a.asm.G).apply(null,arguments)},Ea=a._emscripten_bind_AttributeOctahedronTransform_AttributeOctahedronTransform_0=function(){return(Ea=a._emscripten_bind_AttributeOctahedronTransform_AttributeOctahedronTransform_0=
|
||||
a.asm.H).apply(null,arguments)},rb=a._emscripten_bind_AttributeOctahedronTransform_InitFromAttribute_1=function(){return(rb=a._emscripten_bind_AttributeOctahedronTransform_InitFromAttribute_1=a.asm.I).apply(null,arguments)},sb=a._emscripten_bind_AttributeOctahedronTransform_quantization_bits_0=function(){return(sb=a._emscripten_bind_AttributeOctahedronTransform_quantization_bits_0=a.asm.J).apply(null,arguments)},tb=a._emscripten_bind_AttributeOctahedronTransform___destroy___0=function(){return(tb=
|
||||
a._emscripten_bind_AttributeOctahedronTransform___destroy___0=a.asm.K).apply(null,arguments)},Fa=a._emscripten_bind_PointCloud_PointCloud_0=function(){return(Fa=a._emscripten_bind_PointCloud_PointCloud_0=a.asm.L).apply(null,arguments)},ub=a._emscripten_bind_PointCloud_num_attributes_0=function(){return(ub=a._emscripten_bind_PointCloud_num_attributes_0=a.asm.M).apply(null,arguments)},vb=a._emscripten_bind_PointCloud_num_points_0=function(){return(vb=a._emscripten_bind_PointCloud_num_points_0=a.asm.N).apply(null,
|
||||
arguments)},wb=a._emscripten_bind_PointCloud___destroy___0=function(){return(wb=a._emscripten_bind_PointCloud___destroy___0=a.asm.O).apply(null,arguments)},Ga=a._emscripten_bind_Mesh_Mesh_0=function(){return(Ga=a._emscripten_bind_Mesh_Mesh_0=a.asm.P).apply(null,arguments)},xb=a._emscripten_bind_Mesh_num_faces_0=function(){return(xb=a._emscripten_bind_Mesh_num_faces_0=a.asm.Q).apply(null,arguments)},yb=a._emscripten_bind_Mesh_num_attributes_0=function(){return(yb=a._emscripten_bind_Mesh_num_attributes_0=
|
||||
a.asm.R).apply(null,arguments)},zb=a._emscripten_bind_Mesh_num_points_0=function(){return(zb=a._emscripten_bind_Mesh_num_points_0=a.asm.S).apply(null,arguments)},Ab=a._emscripten_bind_Mesh___destroy___0=function(){return(Ab=a._emscripten_bind_Mesh___destroy___0=a.asm.T).apply(null,arguments)},Ha=a._emscripten_bind_Metadata_Metadata_0=function(){return(Ha=a._emscripten_bind_Metadata_Metadata_0=a.asm.U).apply(null,arguments)},Bb=a._emscripten_bind_Metadata___destroy___0=function(){return(Bb=a._emscripten_bind_Metadata___destroy___0=
|
||||
a.asm.V).apply(null,arguments)},Cb=a._emscripten_bind_Status_code_0=function(){return(Cb=a._emscripten_bind_Status_code_0=a.asm.W).apply(null,arguments)},Db=a._emscripten_bind_Status_ok_0=function(){return(Db=a._emscripten_bind_Status_ok_0=a.asm.X).apply(null,arguments)},Eb=a._emscripten_bind_Status_error_msg_0=function(){return(Eb=a._emscripten_bind_Status_error_msg_0=a.asm.Y).apply(null,arguments)},Fb=a._emscripten_bind_Status___destroy___0=function(){return(Fb=a._emscripten_bind_Status___destroy___0=
|
||||
a.asm.Z).apply(null,arguments)},Ia=a._emscripten_bind_DracoFloat32Array_DracoFloat32Array_0=function(){return(Ia=a._emscripten_bind_DracoFloat32Array_DracoFloat32Array_0=a.asm._).apply(null,arguments)},Gb=a._emscripten_bind_DracoFloat32Array_GetValue_1=function(){return(Gb=a._emscripten_bind_DracoFloat32Array_GetValue_1=a.asm.$).apply(null,arguments)},Hb=a._emscripten_bind_DracoFloat32Array_size_0=function(){return(Hb=a._emscripten_bind_DracoFloat32Array_size_0=a.asm.aa).apply(null,arguments)},Ib=
|
||||
a._emscripten_bind_DracoFloat32Array___destroy___0=function(){return(Ib=a._emscripten_bind_DracoFloat32Array___destroy___0=a.asm.ba).apply(null,arguments)},Ja=a._emscripten_bind_DracoInt8Array_DracoInt8Array_0=function(){return(Ja=a._emscripten_bind_DracoInt8Array_DracoInt8Array_0=a.asm.ca).apply(null,arguments)},Jb=a._emscripten_bind_DracoInt8Array_GetValue_1=function(){return(Jb=a._emscripten_bind_DracoInt8Array_GetValue_1=a.asm.da).apply(null,arguments)},Kb=a._emscripten_bind_DracoInt8Array_size_0=
|
||||
function(){return(Kb=a._emscripten_bind_DracoInt8Array_size_0=a.asm.ea).apply(null,arguments)},Lb=a._emscripten_bind_DracoInt8Array___destroy___0=function(){return(Lb=a._emscripten_bind_DracoInt8Array___destroy___0=a.asm.fa).apply(null,arguments)},Ka=a._emscripten_bind_DracoUInt8Array_DracoUInt8Array_0=function(){return(Ka=a._emscripten_bind_DracoUInt8Array_DracoUInt8Array_0=a.asm.ga).apply(null,arguments)},Mb=a._emscripten_bind_DracoUInt8Array_GetValue_1=function(){return(Mb=a._emscripten_bind_DracoUInt8Array_GetValue_1=
|
||||
a.asm.ha).apply(null,arguments)},Nb=a._emscripten_bind_DracoUInt8Array_size_0=function(){return(Nb=a._emscripten_bind_DracoUInt8Array_size_0=a.asm.ia).apply(null,arguments)},Ob=a._emscripten_bind_DracoUInt8Array___destroy___0=function(){return(Ob=a._emscripten_bind_DracoUInt8Array___destroy___0=a.asm.ja).apply(null,arguments)},La=a._emscripten_bind_DracoInt16Array_DracoInt16Array_0=function(){return(La=a._emscripten_bind_DracoInt16Array_DracoInt16Array_0=a.asm.ka).apply(null,arguments)},Pb=a._emscripten_bind_DracoInt16Array_GetValue_1=
|
||||
function(){return(Pb=a._emscripten_bind_DracoInt16Array_GetValue_1=a.asm.la).apply(null,arguments)},Qb=a._emscripten_bind_DracoInt16Array_size_0=function(){return(Qb=a._emscripten_bind_DracoInt16Array_size_0=a.asm.ma).apply(null,arguments)},Rb=a._emscripten_bind_DracoInt16Array___destroy___0=function(){return(Rb=a._emscripten_bind_DracoInt16Array___destroy___0=a.asm.na).apply(null,arguments)},Ma=a._emscripten_bind_DracoUInt16Array_DracoUInt16Array_0=function(){return(Ma=a._emscripten_bind_DracoUInt16Array_DracoUInt16Array_0=
|
||||
a.asm.oa).apply(null,arguments)},Sb=a._emscripten_bind_DracoUInt16Array_GetValue_1=function(){return(Sb=a._emscripten_bind_DracoUInt16Array_GetValue_1=a.asm.pa).apply(null,arguments)},Tb=a._emscripten_bind_DracoUInt16Array_size_0=function(){return(Tb=a._emscripten_bind_DracoUInt16Array_size_0=a.asm.qa).apply(null,arguments)},Ub=a._emscripten_bind_DracoUInt16Array___destroy___0=function(){return(Ub=a._emscripten_bind_DracoUInt16Array___destroy___0=a.asm.ra).apply(null,arguments)},Na=a._emscripten_bind_DracoInt32Array_DracoInt32Array_0=
|
||||
function(){return(Na=a._emscripten_bind_DracoInt32Array_DracoInt32Array_0=a.asm.sa).apply(null,arguments)},Vb=a._emscripten_bind_DracoInt32Array_GetValue_1=function(){return(Vb=a._emscripten_bind_DracoInt32Array_GetValue_1=a.asm.ta).apply(null,arguments)},Wb=a._emscripten_bind_DracoInt32Array_size_0=function(){return(Wb=a._emscripten_bind_DracoInt32Array_size_0=a.asm.ua).apply(null,arguments)},Xb=a._emscripten_bind_DracoInt32Array___destroy___0=function(){return(Xb=a._emscripten_bind_DracoInt32Array___destroy___0=
|
||||
a.asm.va).apply(null,arguments)},Oa=a._emscripten_bind_DracoUInt32Array_DracoUInt32Array_0=function(){return(Oa=a._emscripten_bind_DracoUInt32Array_DracoUInt32Array_0=a.asm.wa).apply(null,arguments)},Yb=a._emscripten_bind_DracoUInt32Array_GetValue_1=function(){return(Yb=a._emscripten_bind_DracoUInt32Array_GetValue_1=a.asm.xa).apply(null,arguments)},Zb=a._emscripten_bind_DracoUInt32Array_size_0=function(){return(Zb=a._emscripten_bind_DracoUInt32Array_size_0=a.asm.ya).apply(null,arguments)},$b=a._emscripten_bind_DracoUInt32Array___destroy___0=
|
||||
function(){return($b=a._emscripten_bind_DracoUInt32Array___destroy___0=a.asm.za).apply(null,arguments)},Pa=a._emscripten_bind_MetadataQuerier_MetadataQuerier_0=function(){return(Pa=a._emscripten_bind_MetadataQuerier_MetadataQuerier_0=a.asm.Aa).apply(null,arguments)},ac=a._emscripten_bind_MetadataQuerier_HasEntry_2=function(){return(ac=a._emscripten_bind_MetadataQuerier_HasEntry_2=a.asm.Ba).apply(null,arguments)},bc=a._emscripten_bind_MetadataQuerier_GetIntEntry_2=function(){return(bc=a._emscripten_bind_MetadataQuerier_GetIntEntry_2=
|
||||
a.asm.Ca).apply(null,arguments)},cc=a._emscripten_bind_MetadataQuerier_GetIntEntryArray_3=function(){return(cc=a._emscripten_bind_MetadataQuerier_GetIntEntryArray_3=a.asm.Da).apply(null,arguments)},dc=a._emscripten_bind_MetadataQuerier_GetDoubleEntry_2=function(){return(dc=a._emscripten_bind_MetadataQuerier_GetDoubleEntry_2=a.asm.Ea).apply(null,arguments)},ec=a._emscripten_bind_MetadataQuerier_GetStringEntry_2=function(){return(ec=a._emscripten_bind_MetadataQuerier_GetStringEntry_2=a.asm.Fa).apply(null,
|
||||
arguments)},fc=a._emscripten_bind_MetadataQuerier_NumEntries_1=function(){return(fc=a._emscripten_bind_MetadataQuerier_NumEntries_1=a.asm.Ga).apply(null,arguments)},gc=a._emscripten_bind_MetadataQuerier_GetEntryName_2=function(){return(gc=a._emscripten_bind_MetadataQuerier_GetEntryName_2=a.asm.Ha).apply(null,arguments)},hc=a._emscripten_bind_MetadataQuerier___destroy___0=function(){return(hc=a._emscripten_bind_MetadataQuerier___destroy___0=a.asm.Ia).apply(null,arguments)},Qa=a._emscripten_bind_Decoder_Decoder_0=
|
||||
function(){return(Qa=a._emscripten_bind_Decoder_Decoder_0=a.asm.Ja).apply(null,arguments)},ic=a._emscripten_bind_Decoder_DecodeArrayToPointCloud_3=function(){return(ic=a._emscripten_bind_Decoder_DecodeArrayToPointCloud_3=a.asm.Ka).apply(null,arguments)},jc=a._emscripten_bind_Decoder_DecodeArrayToMesh_3=function(){return(jc=a._emscripten_bind_Decoder_DecodeArrayToMesh_3=a.asm.La).apply(null,arguments)},kc=a._emscripten_bind_Decoder_GetAttributeId_2=function(){return(kc=a._emscripten_bind_Decoder_GetAttributeId_2=
|
||||
a.asm.Ma).apply(null,arguments)},lc=a._emscripten_bind_Decoder_GetAttributeIdByName_2=function(){return(lc=a._emscripten_bind_Decoder_GetAttributeIdByName_2=a.asm.Na).apply(null,arguments)},mc=a._emscripten_bind_Decoder_GetAttributeIdByMetadataEntry_3=function(){return(mc=a._emscripten_bind_Decoder_GetAttributeIdByMetadataEntry_3=a.asm.Oa).apply(null,arguments)},nc=a._emscripten_bind_Decoder_GetAttribute_2=function(){return(nc=a._emscripten_bind_Decoder_GetAttribute_2=a.asm.Pa).apply(null,arguments)},
|
||||
oc=a._emscripten_bind_Decoder_GetAttributeByUniqueId_2=function(){return(oc=a._emscripten_bind_Decoder_GetAttributeByUniqueId_2=a.asm.Qa).apply(null,arguments)},pc=a._emscripten_bind_Decoder_GetMetadata_1=function(){return(pc=a._emscripten_bind_Decoder_GetMetadata_1=a.asm.Ra).apply(null,arguments)},qc=a._emscripten_bind_Decoder_GetAttributeMetadata_2=function(){return(qc=a._emscripten_bind_Decoder_GetAttributeMetadata_2=a.asm.Sa).apply(null,arguments)},rc=a._emscripten_bind_Decoder_GetFaceFromMesh_3=
|
||||
function(){return(rc=a._emscripten_bind_Decoder_GetFaceFromMesh_3=a.asm.Ta).apply(null,arguments)},sc=a._emscripten_bind_Decoder_GetTriangleStripsFromMesh_2=function(){return(sc=a._emscripten_bind_Decoder_GetTriangleStripsFromMesh_2=a.asm.Ua).apply(null,arguments)},tc=a._emscripten_bind_Decoder_GetTrianglesUInt16Array_3=function(){return(tc=a._emscripten_bind_Decoder_GetTrianglesUInt16Array_3=a.asm.Va).apply(null,arguments)},uc=a._emscripten_bind_Decoder_GetTrianglesUInt32Array_3=function(){return(uc=
|
||||
a._emscripten_bind_Decoder_GetTrianglesUInt32Array_3=a.asm.Wa).apply(null,arguments)},vc=a._emscripten_bind_Decoder_GetAttributeFloat_3=function(){return(vc=a._emscripten_bind_Decoder_GetAttributeFloat_3=a.asm.Xa).apply(null,arguments)},wc=a._emscripten_bind_Decoder_GetAttributeFloatForAllPoints_3=function(){return(wc=a._emscripten_bind_Decoder_GetAttributeFloatForAllPoints_3=a.asm.Ya).apply(null,arguments)},xc=a._emscripten_bind_Decoder_GetAttributeIntForAllPoints_3=function(){return(xc=a._emscripten_bind_Decoder_GetAttributeIntForAllPoints_3=
|
||||
a.asm.Za).apply(null,arguments)},yc=a._emscripten_bind_Decoder_GetAttributeInt8ForAllPoints_3=function(){return(yc=a._emscripten_bind_Decoder_GetAttributeInt8ForAllPoints_3=a.asm._a).apply(null,arguments)},zc=a._emscripten_bind_Decoder_GetAttributeUInt8ForAllPoints_3=function(){return(zc=a._emscripten_bind_Decoder_GetAttributeUInt8ForAllPoints_3=a.asm.$a).apply(null,arguments)},Ac=a._emscripten_bind_Decoder_GetAttributeInt16ForAllPoints_3=function(){return(Ac=a._emscripten_bind_Decoder_GetAttributeInt16ForAllPoints_3=
|
||||
a.asm.ab).apply(null,arguments)},Bc=a._emscripten_bind_Decoder_GetAttributeUInt16ForAllPoints_3=function(){return(Bc=a._emscripten_bind_Decoder_GetAttributeUInt16ForAllPoints_3=a.asm.bb).apply(null,arguments)},Cc=a._emscripten_bind_Decoder_GetAttributeInt32ForAllPoints_3=function(){return(Cc=a._emscripten_bind_Decoder_GetAttributeInt32ForAllPoints_3=a.asm.cb).apply(null,arguments)},Dc=a._emscripten_bind_Decoder_GetAttributeUInt32ForAllPoints_3=function(){return(Dc=a._emscripten_bind_Decoder_GetAttributeUInt32ForAllPoints_3=
|
||||
a.asm.db).apply(null,arguments)},Ec=a._emscripten_bind_Decoder_GetAttributeDataArrayForAllPoints_5=function(){return(Ec=a._emscripten_bind_Decoder_GetAttributeDataArrayForAllPoints_5=a.asm.eb).apply(null,arguments)},Fc=a._emscripten_bind_Decoder_SkipAttributeTransform_1=function(){return(Fc=a._emscripten_bind_Decoder_SkipAttributeTransform_1=a.asm.fb).apply(null,arguments)},Gc=a._emscripten_bind_Decoder_GetEncodedGeometryType_Deprecated_1=function(){return(Gc=a._emscripten_bind_Decoder_GetEncodedGeometryType_Deprecated_1=
|
||||
a.asm.gb).apply(null,arguments)},Hc=a._emscripten_bind_Decoder_DecodeBufferToPointCloud_2=function(){return(Hc=a._emscripten_bind_Decoder_DecodeBufferToPointCloud_2=a.asm.hb).apply(null,arguments)},Ic=a._emscripten_bind_Decoder_DecodeBufferToMesh_2=function(){return(Ic=a._emscripten_bind_Decoder_DecodeBufferToMesh_2=a.asm.ib).apply(null,arguments)},Jc=a._emscripten_bind_Decoder___destroy___0=function(){return(Jc=a._emscripten_bind_Decoder___destroy___0=a.asm.jb).apply(null,arguments)},Kc=a._emscripten_enum_draco_AttributeTransformType_ATTRIBUTE_INVALID_TRANSFORM=
|
||||
function(){return(Kc=a._emscripten_enum_draco_AttributeTransformType_ATTRIBUTE_INVALID_TRANSFORM=a.asm.kb).apply(null,arguments)},Lc=a._emscripten_enum_draco_AttributeTransformType_ATTRIBUTE_NO_TRANSFORM=function(){return(Lc=a._emscripten_enum_draco_AttributeTransformType_ATTRIBUTE_NO_TRANSFORM=a.asm.lb).apply(null,arguments)},Mc=a._emscripten_enum_draco_AttributeTransformType_ATTRIBUTE_QUANTIZATION_TRANSFORM=function(){return(Mc=a._emscripten_enum_draco_AttributeTransformType_ATTRIBUTE_QUANTIZATION_TRANSFORM=
|
||||
a.asm.mb).apply(null,arguments)},Nc=a._emscripten_enum_draco_AttributeTransformType_ATTRIBUTE_OCTAHEDRON_TRANSFORM=function(){return(Nc=a._emscripten_enum_draco_AttributeTransformType_ATTRIBUTE_OCTAHEDRON_TRANSFORM=a.asm.nb).apply(null,arguments)},Oc=a._emscripten_enum_draco_GeometryAttribute_Type_INVALID=function(){return(Oc=a._emscripten_enum_draco_GeometryAttribute_Type_INVALID=a.asm.ob).apply(null,arguments)},Pc=a._emscripten_enum_draco_GeometryAttribute_Type_POSITION=function(){return(Pc=a._emscripten_enum_draco_GeometryAttribute_Type_POSITION=
|
||||
a.asm.pb).apply(null,arguments)},Qc=a._emscripten_enum_draco_GeometryAttribute_Type_NORMAL=function(){return(Qc=a._emscripten_enum_draco_GeometryAttribute_Type_NORMAL=a.asm.qb).apply(null,arguments)},Rc=a._emscripten_enum_draco_GeometryAttribute_Type_COLOR=function(){return(Rc=a._emscripten_enum_draco_GeometryAttribute_Type_COLOR=a.asm.rb).apply(null,arguments)},Sc=a._emscripten_enum_draco_GeometryAttribute_Type_TEX_COORD=function(){return(Sc=a._emscripten_enum_draco_GeometryAttribute_Type_TEX_COORD=
|
||||
a.asm.sb).apply(null,arguments)},Tc=a._emscripten_enum_draco_GeometryAttribute_Type_GENERIC=function(){return(Tc=a._emscripten_enum_draco_GeometryAttribute_Type_GENERIC=a.asm.tb).apply(null,arguments)},Uc=a._emscripten_enum_draco_EncodedGeometryType_INVALID_GEOMETRY_TYPE=function(){return(Uc=a._emscripten_enum_draco_EncodedGeometryType_INVALID_GEOMETRY_TYPE=a.asm.ub).apply(null,arguments)},Vc=a._emscripten_enum_draco_EncodedGeometryType_POINT_CLOUD=function(){return(Vc=a._emscripten_enum_draco_EncodedGeometryType_POINT_CLOUD=
|
||||
a.asm.vb).apply(null,arguments)},Wc=a._emscripten_enum_draco_EncodedGeometryType_TRIANGULAR_MESH=function(){return(Wc=a._emscripten_enum_draco_EncodedGeometryType_TRIANGULAR_MESH=a.asm.wb).apply(null,arguments)},Xc=a._emscripten_enum_draco_DataType_DT_INVALID=function(){return(Xc=a._emscripten_enum_draco_DataType_DT_INVALID=a.asm.xb).apply(null,arguments)},Yc=a._emscripten_enum_draco_DataType_DT_INT8=function(){return(Yc=a._emscripten_enum_draco_DataType_DT_INT8=a.asm.yb).apply(null,arguments)},Zc=
|
||||
a._emscripten_enum_draco_DataType_DT_UINT8=function(){return(Zc=a._emscripten_enum_draco_DataType_DT_UINT8=a.asm.zb).apply(null,arguments)},$c=a._emscripten_enum_draco_DataType_DT_INT16=function(){return($c=a._emscripten_enum_draco_DataType_DT_INT16=a.asm.Ab).apply(null,arguments)},ad=a._emscripten_enum_draco_DataType_DT_UINT16=function(){return(ad=a._emscripten_enum_draco_DataType_DT_UINT16=a.asm.Bb).apply(null,arguments)},bd=a._emscripten_enum_draco_DataType_DT_INT32=function(){return(bd=a._emscripten_enum_draco_DataType_DT_INT32=
|
||||
a.asm.Cb).apply(null,arguments)},cd=a._emscripten_enum_draco_DataType_DT_UINT32=function(){return(cd=a._emscripten_enum_draco_DataType_DT_UINT32=a.asm.Db).apply(null,arguments)},dd=a._emscripten_enum_draco_DataType_DT_INT64=function(){return(dd=a._emscripten_enum_draco_DataType_DT_INT64=a.asm.Eb).apply(null,arguments)},ed=a._emscripten_enum_draco_DataType_DT_UINT64=function(){return(ed=a._emscripten_enum_draco_DataType_DT_UINT64=a.asm.Fb).apply(null,arguments)},fd=a._emscripten_enum_draco_DataType_DT_FLOAT32=
|
||||
function(){return(fd=a._emscripten_enum_draco_DataType_DT_FLOAT32=a.asm.Gb).apply(null,arguments)},gd=a._emscripten_enum_draco_DataType_DT_FLOAT64=function(){return(gd=a._emscripten_enum_draco_DataType_DT_FLOAT64=a.asm.Hb).apply(null,arguments)},hd=a._emscripten_enum_draco_DataType_DT_BOOL=function(){return(hd=a._emscripten_enum_draco_DataType_DT_BOOL=a.asm.Ib).apply(null,arguments)},id=a._emscripten_enum_draco_DataType_DT_TYPES_COUNT=function(){return(id=a._emscripten_enum_draco_DataType_DT_TYPES_COUNT=
|
||||
a.asm.Jb).apply(null,arguments)},jd=a._emscripten_enum_draco_StatusCode_OK=function(){return(jd=a._emscripten_enum_draco_StatusCode_OK=a.asm.Kb).apply(null,arguments)},kd=a._emscripten_enum_draco_StatusCode_DRACO_ERROR=function(){return(kd=a._emscripten_enum_draco_StatusCode_DRACO_ERROR=a.asm.Lb).apply(null,arguments)},ld=a._emscripten_enum_draco_StatusCode_IO_ERROR=function(){return(ld=a._emscripten_enum_draco_StatusCode_IO_ERROR=a.asm.Mb).apply(null,arguments)},md=a._emscripten_enum_draco_StatusCode_INVALID_PARAMETER=
|
||||
function(){return(md=a._emscripten_enum_draco_StatusCode_INVALID_PARAMETER=a.asm.Nb).apply(null,arguments)},nd=a._emscripten_enum_draco_StatusCode_UNSUPPORTED_VERSION=function(){return(nd=a._emscripten_enum_draco_StatusCode_UNSUPPORTED_VERSION=a.asm.Ob).apply(null,arguments)},od=a._emscripten_enum_draco_StatusCode_UNKNOWN_VERSION=function(){return(od=a._emscripten_enum_draco_StatusCode_UNKNOWN_VERSION=a.asm.Pb).apply(null,arguments)};a._malloc=function(){return(a._malloc=a.asm.Qb).apply(null,arguments)};
|
||||
a._free=function(){return(a._free=a.asm.Rb).apply(null,arguments)};var ua=function(){return(ua=a.asm.Sb).apply(null,arguments)};a.___start_em_js=11660;a.___stop_em_js=11758;var la;ha=function b(){la||F();la||(ha=b)};if(a.preInit)for("function"==typeof a.preInit&&(a.preInit=[a.preInit]);0<a.preInit.length;)a.preInit.pop()();F();v.prototype=Object.create(v.prototype);v.prototype.constructor=v;v.prototype.__class__=v;v.__cache__={};a.WrapperObject=v;a.getCache=w;a.wrapPointer=B;a.castObject=function(b,
|
||||
c){return B(b.ptr,c)};a.NULL=B(0);a.destroy=function(b){if(!b.__destroy__)throw"Error: Cannot destroy object. (Did you create it yourself?)";b.__destroy__();delete w(b.__class__)[b.ptr]};a.compare=function(b,c){return b.ptr===c.ptr};a.getPointer=function(b){return b.ptr};a.getClass=function(b){return b.__class__};var r={buffer:0,size:0,pos:0,temps:[],needed:0,prepare:function(){if(r.needed){for(var b=0;b<r.temps.length;b++)a._free(r.temps[b]);r.temps.length=0;a._free(r.buffer);r.buffer=0;r.size+=
|
||||
r.needed;r.needed=0}r.buffer||(r.size+=128,r.buffer=a._malloc(r.size),r.buffer||y(void 0));r.pos=0},alloc:function(b,c){r.buffer||y(void 0);b=b.length*c.BYTES_PER_ELEMENT;b=b+7&-8;r.pos+b>=r.size?(0<b||y(void 0),r.needed+=b,c=a._malloc(b),r.temps.push(c)):(c=r.buffer+r.pos,r.pos+=b);return c},copy:function(b,c,d){d>>>=0;switch(c.BYTES_PER_ELEMENT){case 2:d>>>=1;break;case 4:d>>>=2;break;case 8:d>>>=3}for(var g=0;g<b.length;g++)c[d+g]=b[g]}};X.prototype=Object.create(v.prototype);X.prototype.constructor=
|
||||
X;X.prototype.__class__=X;X.__cache__={};a.VoidPtr=X;X.prototype.__destroy__=X.prototype.__destroy__=function(){Xa(this.ptr)};S.prototype=Object.create(v.prototype);S.prototype.constructor=S;S.prototype.__class__=S;S.__cache__={};a.DecoderBuffer=S;S.prototype.Init=S.prototype.Init=function(b,c){var d=this.ptr;r.prepare();"object"==typeof b&&(b=Z(b));c&&"object"===typeof c&&(c=c.ptr);Ya(d,b,c)};S.prototype.__destroy__=S.prototype.__destroy__=function(){Za(this.ptr)};Q.prototype=Object.create(v.prototype);
|
||||
Q.prototype.constructor=Q;Q.prototype.__class__=Q;Q.__cache__={};a.AttributeTransformData=Q;Q.prototype.transform_type=Q.prototype.transform_type=function(){return $a(this.ptr)};Q.prototype.__destroy__=Q.prototype.__destroy__=function(){ab(this.ptr)};V.prototype=Object.create(v.prototype);V.prototype.constructor=V;V.prototype.__class__=V;V.__cache__={};a.GeometryAttribute=V;V.prototype.__destroy__=V.prototype.__destroy__=function(){bb(this.ptr)};x.prototype=Object.create(v.prototype);x.prototype.constructor=
|
||||
x;x.prototype.__class__=x;x.__cache__={};a.PointAttribute=x;x.prototype.size=x.prototype.size=function(){return cb(this.ptr)};x.prototype.GetAttributeTransformData=x.prototype.GetAttributeTransformData=function(){return B(db(this.ptr),Q)};x.prototype.attribute_type=x.prototype.attribute_type=function(){return eb(this.ptr)};x.prototype.data_type=x.prototype.data_type=function(){return fb(this.ptr)};x.prototype.num_components=x.prototype.num_components=function(){return gb(this.ptr)};x.prototype.normalized=
|
||||
x.prototype.normalized=function(){return!!hb(this.ptr)};x.prototype.byte_stride=x.prototype.byte_stride=function(){return ib(this.ptr)};x.prototype.byte_offset=x.prototype.byte_offset=function(){return jb(this.ptr)};x.prototype.unique_id=x.prototype.unique_id=function(){return kb(this.ptr)};x.prototype.__destroy__=x.prototype.__destroy__=function(){lb(this.ptr)};D.prototype=Object.create(v.prototype);D.prototype.constructor=D;D.prototype.__class__=D;D.__cache__={};a.AttributeQuantizationTransform=
|
||||
D;D.prototype.InitFromAttribute=D.prototype.InitFromAttribute=function(b){var c=this.ptr;b&&"object"===typeof b&&(b=b.ptr);return!!mb(c,b)};D.prototype.quantization_bits=D.prototype.quantization_bits=function(){return nb(this.ptr)};D.prototype.min_value=D.prototype.min_value=function(b){var c=this.ptr;b&&"object"===typeof b&&(b=b.ptr);return ob(c,b)};D.prototype.range=D.prototype.range=function(){return pb(this.ptr)};D.prototype.__destroy__=D.prototype.__destroy__=function(){qb(this.ptr)};G.prototype=
|
||||
Object.create(v.prototype);G.prototype.constructor=G;G.prototype.__class__=G;G.__cache__={};a.AttributeOctahedronTransform=G;G.prototype.InitFromAttribute=G.prototype.InitFromAttribute=function(b){var c=this.ptr;b&&"object"===typeof b&&(b=b.ptr);return!!rb(c,b)};G.prototype.quantization_bits=G.prototype.quantization_bits=function(){return sb(this.ptr)};G.prototype.__destroy__=G.prototype.__destroy__=function(){tb(this.ptr)};H.prototype=Object.create(v.prototype);H.prototype.constructor=H;H.prototype.__class__=
|
||||
H;H.__cache__={};a.PointCloud=H;H.prototype.num_attributes=H.prototype.num_attributes=function(){return ub(this.ptr)};H.prototype.num_points=H.prototype.num_points=function(){return vb(this.ptr)};H.prototype.__destroy__=H.prototype.__destroy__=function(){wb(this.ptr)};E.prototype=Object.create(v.prototype);E.prototype.constructor=E;E.prototype.__class__=E;E.__cache__={};a.Mesh=E;E.prototype.num_faces=E.prototype.num_faces=function(){return xb(this.ptr)};E.prototype.num_attributes=E.prototype.num_attributes=
|
||||
function(){return yb(this.ptr)};E.prototype.num_points=E.prototype.num_points=function(){return zb(this.ptr)};E.prototype.__destroy__=E.prototype.__destroy__=function(){Ab(this.ptr)};T.prototype=Object.create(v.prototype);T.prototype.constructor=T;T.prototype.__class__=T;T.__cache__={};a.Metadata=T;T.prototype.__destroy__=T.prototype.__destroy__=function(){Bb(this.ptr)};C.prototype=Object.create(v.prototype);C.prototype.constructor=C;C.prototype.__class__=C;C.__cache__={};a.Status=C;C.prototype.code=
|
||||
C.prototype.code=function(){return Cb(this.ptr)};C.prototype.ok=C.prototype.ok=function(){return!!Db(this.ptr)};C.prototype.error_msg=C.prototype.error_msg=function(){return p(Eb(this.ptr))};C.prototype.__destroy__=C.prototype.__destroy__=function(){Fb(this.ptr)};I.prototype=Object.create(v.prototype);I.prototype.constructor=I;I.prototype.__class__=I;I.__cache__={};a.DracoFloat32Array=I;I.prototype.GetValue=I.prototype.GetValue=function(b){var c=this.ptr;b&&"object"===typeof b&&(b=b.ptr);return Gb(c,
|
||||
b)};I.prototype.size=I.prototype.size=function(){return Hb(this.ptr)};I.prototype.__destroy__=I.prototype.__destroy__=function(){Ib(this.ptr)};J.prototype=Object.create(v.prototype);J.prototype.constructor=J;J.prototype.__class__=J;J.__cache__={};a.DracoInt8Array=J;J.prototype.GetValue=J.prototype.GetValue=function(b){var c=this.ptr;b&&"object"===typeof b&&(b=b.ptr);return Jb(c,b)};J.prototype.size=J.prototype.size=function(){return Kb(this.ptr)};J.prototype.__destroy__=J.prototype.__destroy__=function(){Lb(this.ptr)};
|
||||
K.prototype=Object.create(v.prototype);K.prototype.constructor=K;K.prototype.__class__=K;K.__cache__={};a.DracoUInt8Array=K;K.prototype.GetValue=K.prototype.GetValue=function(b){var c=this.ptr;b&&"object"===typeof b&&(b=b.ptr);return Mb(c,b)};K.prototype.size=K.prototype.size=function(){return Nb(this.ptr)};K.prototype.__destroy__=K.prototype.__destroy__=function(){Ob(this.ptr)};L.prototype=Object.create(v.prototype);L.prototype.constructor=L;L.prototype.__class__=L;L.__cache__={};a.DracoInt16Array=
|
||||
L;L.prototype.GetValue=L.prototype.GetValue=function(b){var c=this.ptr;b&&"object"===typeof b&&(b=b.ptr);return Pb(c,b)};L.prototype.size=L.prototype.size=function(){return Qb(this.ptr)};L.prototype.__destroy__=L.prototype.__destroy__=function(){Rb(this.ptr)};M.prototype=Object.create(v.prototype);M.prototype.constructor=M;M.prototype.__class__=M;M.__cache__={};a.DracoUInt16Array=M;M.prototype.GetValue=M.prototype.GetValue=function(b){var c=this.ptr;b&&"object"===typeof b&&(b=b.ptr);return Sb(c,b)};
|
||||
M.prototype.size=M.prototype.size=function(){return Tb(this.ptr)};M.prototype.__destroy__=M.prototype.__destroy__=function(){Ub(this.ptr)};N.prototype=Object.create(v.prototype);N.prototype.constructor=N;N.prototype.__class__=N;N.__cache__={};a.DracoInt32Array=N;N.prototype.GetValue=N.prototype.GetValue=function(b){var c=this.ptr;b&&"object"===typeof b&&(b=b.ptr);return Vb(c,b)};N.prototype.size=N.prototype.size=function(){return Wb(this.ptr)};N.prototype.__destroy__=N.prototype.__destroy__=function(){Xb(this.ptr)};
|
||||
O.prototype=Object.create(v.prototype);O.prototype.constructor=O;O.prototype.__class__=O;O.__cache__={};a.DracoUInt32Array=O;O.prototype.GetValue=O.prototype.GetValue=function(b){var c=this.ptr;b&&"object"===typeof b&&(b=b.ptr);return Yb(c,b)};O.prototype.size=O.prototype.size=function(){return Zb(this.ptr)};O.prototype.__destroy__=O.prototype.__destroy__=function(){$b(this.ptr)};z.prototype=Object.create(v.prototype);z.prototype.constructor=z;z.prototype.__class__=z;z.__cache__={};a.MetadataQuerier=
|
||||
z;z.prototype.HasEntry=z.prototype.HasEntry=function(b,c){var d=this.ptr;r.prepare();b&&"object"===typeof b&&(b=b.ptr);c=c&&"object"===typeof c?c.ptr:R(c);return!!ac(d,b,c)};z.prototype.GetIntEntry=z.prototype.GetIntEntry=function(b,c){var d=this.ptr;r.prepare();b&&"object"===typeof b&&(b=b.ptr);c=c&&"object"===typeof c?c.ptr:R(c);return bc(d,b,c)};z.prototype.GetIntEntryArray=z.prototype.GetIntEntryArray=function(b,c,d){var g=this.ptr;r.prepare();b&&"object"===typeof b&&(b=b.ptr);c=c&&"object"===
|
||||
typeof c?c.ptr:R(c);d&&"object"===typeof d&&(d=d.ptr);cc(g,b,c,d)};z.prototype.GetDoubleEntry=z.prototype.GetDoubleEntry=function(b,c){var d=this.ptr;r.prepare();b&&"object"===typeof b&&(b=b.ptr);c=c&&"object"===typeof c?c.ptr:R(c);return dc(d,b,c)};z.prototype.GetStringEntry=z.prototype.GetStringEntry=function(b,c){var d=this.ptr;r.prepare();b&&"object"===typeof b&&(b=b.ptr);c=c&&"object"===typeof c?c.ptr:R(c);return p(ec(d,b,c))};z.prototype.NumEntries=z.prototype.NumEntries=function(b){var c=this.ptr;
|
||||
b&&"object"===typeof b&&(b=b.ptr);return fc(c,b)};z.prototype.GetEntryName=z.prototype.GetEntryName=function(b,c){var d=this.ptr;b&&"object"===typeof b&&(b=b.ptr);c&&"object"===typeof c&&(c=c.ptr);return p(gc(d,b,c))};z.prototype.__destroy__=z.prototype.__destroy__=function(){hc(this.ptr)};m.prototype=Object.create(v.prototype);m.prototype.constructor=m;m.prototype.__class__=m;m.__cache__={};a.Decoder=m;m.prototype.DecodeArrayToPointCloud=m.prototype.DecodeArrayToPointCloud=function(b,c,d){var g=
|
||||
this.ptr;r.prepare();"object"==typeof b&&(b=Z(b));c&&"object"===typeof c&&(c=c.ptr);d&&"object"===typeof d&&(d=d.ptr);return B(ic(g,b,c,d),C)};m.prototype.DecodeArrayToMesh=m.prototype.DecodeArrayToMesh=function(b,c,d){var g=this.ptr;r.prepare();"object"==typeof b&&(b=Z(b));c&&"object"===typeof c&&(c=c.ptr);d&&"object"===typeof d&&(d=d.ptr);return B(jc(g,b,c,d),C)};m.prototype.GetAttributeId=m.prototype.GetAttributeId=function(b,c){var d=this.ptr;b&&"object"===typeof b&&(b=b.ptr);c&&"object"===typeof c&&
|
||||
(c=c.ptr);return kc(d,b,c)};m.prototype.GetAttributeIdByName=m.prototype.GetAttributeIdByName=function(b,c){var d=this.ptr;r.prepare();b&&"object"===typeof b&&(b=b.ptr);c=c&&"object"===typeof c?c.ptr:R(c);return lc(d,b,c)};m.prototype.GetAttributeIdByMetadataEntry=m.prototype.GetAttributeIdByMetadataEntry=function(b,c,d){var g=this.ptr;r.prepare();b&&"object"===typeof b&&(b=b.ptr);c=c&&"object"===typeof c?c.ptr:R(c);d=d&&"object"===typeof d?d.ptr:R(d);return mc(g,b,c,d)};m.prototype.GetAttribute=
|
||||
m.prototype.GetAttribute=function(b,c){var d=this.ptr;b&&"object"===typeof b&&(b=b.ptr);c&&"object"===typeof c&&(c=c.ptr);return B(nc(d,b,c),x)};m.prototype.GetAttributeByUniqueId=m.prototype.GetAttributeByUniqueId=function(b,c){var d=this.ptr;b&&"object"===typeof b&&(b=b.ptr);c&&"object"===typeof c&&(c=c.ptr);return B(oc(d,b,c),x)};m.prototype.GetMetadata=m.prototype.GetMetadata=function(b){var c=this.ptr;b&&"object"===typeof b&&(b=b.ptr);return B(pc(c,b),T)};m.prototype.GetAttributeMetadata=m.prototype.GetAttributeMetadata=
|
||||
function(b,c){var d=this.ptr;b&&"object"===typeof b&&(b=b.ptr);c&&"object"===typeof c&&(c=c.ptr);return B(qc(d,b,c),T)};m.prototype.GetFaceFromMesh=m.prototype.GetFaceFromMesh=function(b,c,d){var g=this.ptr;b&&"object"===typeof b&&(b=b.ptr);c&&"object"===typeof c&&(c=c.ptr);d&&"object"===typeof d&&(d=d.ptr);return!!rc(g,b,c,d)};m.prototype.GetTriangleStripsFromMesh=m.prototype.GetTriangleStripsFromMesh=function(b,c){var d=this.ptr;b&&"object"===typeof b&&(b=b.ptr);c&&"object"===typeof c&&(c=c.ptr);
|
||||
return sc(d,b,c)};m.prototype.GetTrianglesUInt16Array=m.prototype.GetTrianglesUInt16Array=function(b,c,d){var g=this.ptr;b&&"object"===typeof b&&(b=b.ptr);c&&"object"===typeof c&&(c=c.ptr);d&&"object"===typeof d&&(d=d.ptr);return!!tc(g,b,c,d)};m.prototype.GetTrianglesUInt32Array=m.prototype.GetTrianglesUInt32Array=function(b,c,d){var g=this.ptr;b&&"object"===typeof b&&(b=b.ptr);c&&"object"===typeof c&&(c=c.ptr);d&&"object"===typeof d&&(d=d.ptr);return!!uc(g,b,c,d)};m.prototype.GetAttributeFloat=m.prototype.GetAttributeFloat=
|
||||
function(b,c,d){var g=this.ptr;b&&"object"===typeof b&&(b=b.ptr);c&&"object"===typeof c&&(c=c.ptr);d&&"object"===typeof d&&(d=d.ptr);return!!vc(g,b,c,d)};m.prototype.GetAttributeFloatForAllPoints=m.prototype.GetAttributeFloatForAllPoints=function(b,c,d){var g=this.ptr;b&&"object"===typeof b&&(b=b.ptr);c&&"object"===typeof c&&(c=c.ptr);d&&"object"===typeof d&&(d=d.ptr);return!!wc(g,b,c,d)};m.prototype.GetAttributeIntForAllPoints=m.prototype.GetAttributeIntForAllPoints=function(b,c,d){var g=this.ptr;
|
||||
b&&"object"===typeof b&&(b=b.ptr);c&&"object"===typeof c&&(c=c.ptr);d&&"object"===typeof d&&(d=d.ptr);return!!xc(g,b,c,d)};m.prototype.GetAttributeInt8ForAllPoints=m.prototype.GetAttributeInt8ForAllPoints=function(b,c,d){var g=this.ptr;b&&"object"===typeof b&&(b=b.ptr);c&&"object"===typeof c&&(c=c.ptr);d&&"object"===typeof d&&(d=d.ptr);return!!yc(g,b,c,d)};m.prototype.GetAttributeUInt8ForAllPoints=m.prototype.GetAttributeUInt8ForAllPoints=function(b,c,d){var g=this.ptr;b&&"object"===typeof b&&(b=
|
||||
b.ptr);c&&"object"===typeof c&&(c=c.ptr);d&&"object"===typeof d&&(d=d.ptr);return!!zc(g,b,c,d)};m.prototype.GetAttributeInt16ForAllPoints=m.prototype.GetAttributeInt16ForAllPoints=function(b,c,d){var g=this.ptr;b&&"object"===typeof b&&(b=b.ptr);c&&"object"===typeof c&&(c=c.ptr);d&&"object"===typeof d&&(d=d.ptr);return!!Ac(g,b,c,d)};m.prototype.GetAttributeUInt16ForAllPoints=m.prototype.GetAttributeUInt16ForAllPoints=function(b,c,d){var g=this.ptr;b&&"object"===typeof b&&(b=b.ptr);c&&"object"===typeof c&&
|
||||
(c=c.ptr);d&&"object"===typeof d&&(d=d.ptr);return!!Bc(g,b,c,d)};m.prototype.GetAttributeInt32ForAllPoints=m.prototype.GetAttributeInt32ForAllPoints=function(b,c,d){var g=this.ptr;b&&"object"===typeof b&&(b=b.ptr);c&&"object"===typeof c&&(c=c.ptr);d&&"object"===typeof d&&(d=d.ptr);return!!Cc(g,b,c,d)};m.prototype.GetAttributeUInt32ForAllPoints=m.prototype.GetAttributeUInt32ForAllPoints=function(b,c,d){var g=this.ptr;b&&"object"===typeof b&&(b=b.ptr);c&&"object"===typeof c&&(c=c.ptr);d&&"object"===
|
||||
typeof d&&(d=d.ptr);return!!Dc(g,b,c,d)};m.prototype.GetAttributeDataArrayForAllPoints=m.prototype.GetAttributeDataArrayForAllPoints=function(b,c,d,g,t){var aa=this.ptr;b&&"object"===typeof b&&(b=b.ptr);c&&"object"===typeof c&&(c=c.ptr);d&&"object"===typeof d&&(d=d.ptr);g&&"object"===typeof g&&(g=g.ptr);t&&"object"===typeof t&&(t=t.ptr);return!!Ec(aa,b,c,d,g,t)};m.prototype.SkipAttributeTransform=m.prototype.SkipAttributeTransform=function(b){var c=this.ptr;b&&"object"===typeof b&&(b=b.ptr);Fc(c,
|
||||
b)};m.prototype.GetEncodedGeometryType_Deprecated=m.prototype.GetEncodedGeometryType_Deprecated=function(b){var c=this.ptr;b&&"object"===typeof b&&(b=b.ptr);return Gc(c,b)};m.prototype.DecodeBufferToPointCloud=m.prototype.DecodeBufferToPointCloud=function(b,c){var d=this.ptr;b&&"object"===typeof b&&(b=b.ptr);c&&"object"===typeof c&&(c=c.ptr);return B(Hc(d,b,c),C)};m.prototype.DecodeBufferToMesh=m.prototype.DecodeBufferToMesh=function(b,c){var d=this.ptr;b&&"object"===typeof b&&(b=b.ptr);c&&"object"===
|
||||
typeof c&&(c=c.ptr);return B(Ic(d,b,c),C)};m.prototype.__destroy__=m.prototype.__destroy__=function(){Jc(this.ptr)};(function(){function b(){a.ATTRIBUTE_INVALID_TRANSFORM=Kc();a.ATTRIBUTE_NO_TRANSFORM=Lc();a.ATTRIBUTE_QUANTIZATION_TRANSFORM=Mc();a.ATTRIBUTE_OCTAHEDRON_TRANSFORM=Nc();a.INVALID=Oc();a.POSITION=Pc();a.NORMAL=Qc();a.COLOR=Rc();a.TEX_COORD=Sc();a.GENERIC=Tc();a.INVALID_GEOMETRY_TYPE=Uc();a.POINT_CLOUD=Vc();a.TRIANGULAR_MESH=Wc();a.DT_INVALID=Xc();a.DT_INT8=Yc();a.DT_UINT8=Zc();a.DT_INT16=
|
||||
$c();a.DT_UINT16=ad();a.DT_INT32=bd();a.DT_UINT32=cd();a.DT_INT64=dd();a.DT_UINT64=ed();a.DT_FLOAT32=fd();a.DT_FLOAT64=gd();a.DT_BOOL=hd();a.DT_TYPES_COUNT=id();a.OK=jd();a.DRACO_ERROR=kd();a.IO_ERROR=ld();a.INVALID_PARAMETER=md();a.UNSUPPORTED_VERSION=nd();a.UNKNOWN_VERSION=od()}va?b():oa.unshift(b)})();if("function"===typeof a.onModuleParsed)a.onModuleParsed();a.Decoder.prototype.GetEncodedGeometryType=function(b){if(b.__class__&&b.__class__===a.DecoderBuffer)return a.Decoder.prototype.GetEncodedGeometryType_Deprecated(b);
|
||||
if(8>b.byteLength)return a.INVALID_GEOMETRY_TYPE;switch(b[7]){case 0:return a.POINT_CLOUD;case 1:return a.TRIANGULAR_MESH;default:return a.INVALID_GEOMETRY_TYPE}};return n.ready}}();"object"===typeof exports&&"object"===typeof module?module.exports=DracoDecoderModule:"function"===typeof define&&define.amd?define([],function(){return DracoDecoderModule}):"object"===typeof exports&&(exports.DracoDecoderModule=DracoDecoderModule);
|
||||
BIN
public/favicon-16x16.png
Normal file
|
After Width: | Height: | Size: 784 B |
BIN
public/favicon-32x32.png
Normal file
|
After Width: | Height: | Size: 1.9 KiB |
BIN
public/favicon.ico
Normal file
|
After Width: | Height: | Size: 15 KiB |
BIN
public/logos/chorus-landscape-on-blue.png
Normal file
|
After Width: | Height: | Size: 38 KiB |
BIN
public/logos/chorus-landscape-on-grey.png
Normal file
|
After Width: | Height: | Size: 35 KiB |
BIN
public/logos/chorus-landscape-on-mulberry.png
Normal file
|
After Width: | Height: | Size: 36 KiB |
BIN
public/logos/chorus-landscape-on-white.png
Normal file
|
After Width: | Height: | Size: 39 KiB |
205
public/logos/chorus-logo-concept.md
Normal file
@@ -0,0 +1,205 @@
|
||||
# CHORUS Services Logo Design Concept
|
||||
|
||||
## Design Philosophy
|
||||
|
||||
The CHORUS logo embodies distributed AI orchestration through visual metaphors of:
|
||||
- **Musical Harmony**: References to orchestral coordination and symphony
|
||||
- **Distributed Networks**: Interconnected nodes representing AI agent coordination
|
||||
- **Technological Precision**: Clean, modern aesthetic reflecting enterprise software
|
||||
- **Scalable Modularity**: System that combines elegantly with component logos
|
||||
|
||||
## Primary Logo Concept: "The Orchestration Mark"
|
||||
|
||||
### Visual Description
|
||||
The CHORUS logo consists of three core elements:
|
||||
|
||||
#### 1. The Orchestration Symbol (Icon Mark)
|
||||
- **Shape**: A stylized conductor's baton formed by interconnected nodes
|
||||
- **Metaphor**: Represents the orchestration of distributed AI agents
|
||||
- **Structure**:
|
||||
- Central hub (conductor's handle) with 5 radiating connections
|
||||
- Each connection represents a core component (WHOOSH, BZZZ, SLURP, COOEE, Monitoring)
|
||||
- Nodes are connected by elegant, curved lines suggesting harmony and flow
|
||||
- Overall shape creates an abstract musical note when viewed as a whole
|
||||
|
||||
#### 2. The Wordmark (Typography)
|
||||
- **Typeface**: Custom-modified SF Pro Display (Apple-inspired)
|
||||
- **Style**:
|
||||
- **CHORUS**: Bold, slightly condensed, letter-spacing optimized for readability
|
||||
- **Services**: Medium weight, smaller size, positioned below or to the right
|
||||
- **Modifications**:
|
||||
- Slightly rounded corners on letterforms for approachability
|
||||
- Custom "O" in CHORUS designed to echo the orchestration symbol
|
||||
- Subtle geometric adjustments for perfect optical alignment
|
||||
|
||||
#### 3. The Complete Logo System
|
||||
- **Horizontal Layout**: Icon + Wordmark side-by-side (primary)
|
||||
- **Stacked Layout**: Icon above wordmark (vertical applications)
|
||||
- **Icon-Only**: Orchestration symbol standalone (favicon, social media)
|
||||
- **Wordmark-Only**: Text without icon (tight space applications)
|
||||
|
||||
## Color Specifications
|
||||
|
||||
### Primary Version (Dark Backgrounds)
|
||||
- **Icon**: Natural Paper (#F5F5DC) with Orchestration Blue (#007AFF) accent on central hub
|
||||
- **CHORUS Text**: Natural Paper (#F5F5DC)
|
||||
- **Services Text**: Brushed Aluminum (#C0C0C0)
|
||||
- **Background**: Carbon Black (#000000) or transparent
|
||||
|
||||
### Reversed Version (Light Backgrounds)
|
||||
- **Icon**: Carbon Black (#000000) with Orchestration Blue (#007AFF) accent
|
||||
- **CHORUS Text**: Carbon Black (#000000)
|
||||
- **Services Text**: Walnut Brown (#8B4513)
|
||||
- **Background**: Natural Paper (#F5F5DC) or White (#FFFFFF)
|
||||
|
||||
### Monochrome Versions
|
||||
- **Black**: All elements in Carbon Black (#000000)
|
||||
- **White**: All elements in Natural Paper (#F5F5DC)
|
||||
- **Single Color**: All elements in Orchestration Blue (#007AFF)
|
||||
|
||||
## Modular Component System
|
||||
|
||||
### Component Integration Framework
|
||||
Each component logo follows the pattern: **Component Icon + CHORUS Brand Mark**
|
||||
|
||||
#### WHOOSH + CHORUS
|
||||
- **Component Icon**: Stylized orchestration podium/dashboard
|
||||
- **Arrangement**: WHOOSH icon connects to CHORUS orchestration symbol
|
||||
- **Usage**: "WHOOSH powered by CHORUS" applications
|
||||
|
||||
#### BZZZ + CHORUS
|
||||
- **Component Icon**: Hexagonal mesh network pattern (honeycomb reference)
|
||||
- **Arrangement**: BZZZ mesh integrates with CHORUS node connections
|
||||
- **Usage**: P2P networking and coordination materials
|
||||
|
||||
#### SLURP + CHORUS
|
||||
- **Component Icon**: Layered context hierarchy (stacked information layers)
|
||||
- **Arrangement**: SLURP layers flow into CHORUS orchestration hub
|
||||
- **Usage**: Context management and curation applications
|
||||
|
||||
#### COOEE + CHORUS
|
||||
- **Component Icon**: Feedback loop with learning arrows
|
||||
- **Arrangement**: COOEE loop surrounds one node of CHORUS symbol
|
||||
- **Usage**: Learning and feedback system materials
|
||||
|
||||
#### Monitoring + CHORUS
|
||||
- **Component Icon**: Dashboard with metric visualization
|
||||
- **Arrangement**: Monitoring graphs emanate from CHORUS central hub
|
||||
- **Usage**: Analytics and monitoring dashboards
|
||||
|
||||
## Technical Specifications
|
||||
|
||||
### Logo Dimensions
|
||||
- **Minimum Size**: 24px height (digital), 0.5" height (print)
|
||||
- **Optimal Sizes**: 48px, 96px, 192px, 512px (digital icons)
|
||||
- **Aspect Ratio**: 3:2 (horizontal), 1:1 (icon only), 2:3 (stacked)
|
||||
|
||||
### Clear Space
|
||||
- **Rule**: Minimum clear space equals the height of the "C" in CHORUS
|
||||
- **Application**: Applies to all sides of the logo in any configuration
|
||||
- **Exception**: When used in dedicated logo areas (website headers, business cards)
|
||||
|
||||
### Typography Specifications
|
||||
- **CHORUS**:
|
||||
- Font: SF Pro Display Bold (custom-modified)
|
||||
- Size Relationship: 100% (base size)
|
||||
- Letter Spacing: -0.02em (tighter for bold weight)
|
||||
- Line Height: 1.0 (tight for display use)
|
||||
|
||||
- **Services**:
|
||||
- Font: SF Pro Display Medium
|
||||
- Size Relationship: 40% of CHORUS height
|
||||
- Letter Spacing: 0.01em (slightly looser for medium weight)
|
||||
- Position: Baseline aligned with bottom of CHORUS, or centered vertically
|
||||
|
||||
### Color Values
|
||||
css
|
||||
/* Primary Brand Colors */
|
||||
--logo-primary-text: #F5F5DC; /* Natural Paper */
|
||||
--logo-secondary-text: #C0C0C0; /* Brushed Aluminum */
|
||||
--logo-accent: #007AFF; /* Orchestration Blue */
|
||||
--logo-background-dark: #000000; /* Carbon Black */
|
||||
|
||||
/* Reversed Colors */
|
||||
--logo-primary-text-rev: #000000; /* Carbon Black */
|
||||
--logo-secondary-text-rev: #8B4513; /* Walnut Brown */
|
||||
--logo-background-light: #F5F5DC; /* Natural Paper */
|
||||
|
||||
|
||||
## Usage Guidelines
|
||||
|
||||
### Approved Applications
|
||||
- Website headers and navigation
|
||||
- Business cards and letterhead
|
||||
- Digital presentations and documents
|
||||
- Social media profiles and posts
|
||||
- Marketing materials and advertisements
|
||||
- Product packaging and merchandise
|
||||
- Trade show displays and signage
|
||||
|
||||
### Logo Don'ts
|
||||
- Never stretch or distort the logo proportions
|
||||
- Don't use colors outside the approved palette
|
||||
- Never place on backgrounds that fail contrast requirements
|
||||
- Don't add effects (shadows, outlines, gradients) to the logo
|
||||
- Never alter the spacing between elements
|
||||
- Don't use low-resolution versions for print applications
|
||||
|
||||
### Background Requirements
|
||||
- **Dark Backgrounds**: Use primary version with light elements
|
||||
- **Light Backgrounds**: Use reversed version with dark elements
|
||||
- **Complex Backgrounds**: Place logo on solid color field within clear space
|
||||
- **Photographs**: Use high-contrast version with background overlay if needed
|
||||
|
||||
## Logo Variations by Context
|
||||
|
||||
### Digital Applications
|
||||
- **Website Header**: Horizontal layout, medium size (48-64px height)
|
||||
- **Favicon**: Icon-only version, 32x32px minimum
|
||||
- **Social Media Profile**: Icon-only version, square format
|
||||
- **App Icons**: Icon-only with rounded corners, various iOS/Android sizes
|
||||
|
||||
### Print Applications
|
||||
- **Business Cards**: Horizontal layout, 0.75" height maximum
|
||||
- **Letterhead**: Horizontal layout, top-left or center placement
|
||||
- **Brochures**: Various sizes, ensure minimum 0.5" height
|
||||
- **Large Format**: Stacked version works well for banners and signage
|
||||
|
||||
### Component-Specific Applications
|
||||
- **Technical Documentation**: Component + CHORUS combined marks
|
||||
- **API Documentation**: Simplified monochrome versions
|
||||
- **Dashboard UI**: Icon-only versions as navigation elements
|
||||
- **Marketing Materials**: Full brand system with component integration
|
||||
|
||||
## Accessibility Considerations
|
||||
|
||||
### Contrast Standards
|
||||
- All logo versions meet WCAG 2.1 AA contrast requirements
|
||||
- Minimum 4.5:1 contrast ratio for text elements
|
||||
- 3:1 contrast ratio for non-text elements (icon shapes)
|
||||
|
||||
### Alternative Formats
|
||||
- High-contrast versions for accessibility compliance
|
||||
- Text-only versions for screen readers (alt text: "CHORUS Services")
|
||||
- Simplified versions for low-resolution displays
|
||||
- Monochrome versions for single-color printing
|
||||
|
||||
## File Format Specifications
|
||||
|
||||
### Vector Formats (Preferred)
|
||||
- **SVG**: Web use, scalable, smallest file size
|
||||
- **AI/EPS**: Adobe Illustrator native, print production
|
||||
- **PDF**: Print-ready, font embedded
|
||||
|
||||
### Raster Formats (Specific Use)
|
||||
- **PNG**: Transparent backgrounds, web use
|
||||
- **JPG**: Photography integration, solid backgrounds only
|
||||
- **WebP**: Modern web format, smaller file sizes
|
||||
|
||||
### Recommended Export Settings
|
||||
- **Web**: SVG (optimized), PNG at 2x resolution (Retina)
|
||||
- **Print**: Vector formats preferred, 300 DPI minimum for rasters
|
||||
- **Social Media**: PNG at platform-specific dimensions
|
||||
- **App Icons**: PNG at required iOS/Android specifications
|
||||
|
||||
This logo concept provides CHORUS Services with a sophisticated, scalable visual identity that reflects the platform's technical capabilities while maintaining the premium, approachable aesthetic required for enterprise clients.
|
||||
BIN
public/logos/chorus-logo.png
Normal file
|
After Width: | Height: | Size: 105 KiB |
BIN
public/logos/chorus-mobius-on-blue.png
Normal file
|
After Width: | Height: | Size: 100 KiB |
BIN
public/logos/chorus-mobius-on-grey.png
Normal file
|
After Width: | Height: | Size: 104 KiB |
BIN
public/logos/chorus-mobius-on-mulberry.png
Normal file
|
After Width: | Height: | Size: 104 KiB |
BIN
public/logos/chorus-mobius-on-white.png
Normal file
|
After Width: | Height: | Size: 117 KiB |
266
public/logos/component-logo-system.md
Normal file
@@ -0,0 +1,266 @@
|
||||
# CHORUS Services Component Logo System
|
||||
|
||||
## Modular Design Philosophy
|
||||
|
||||
The CHORUS component logo system creates visual harmony between the main brand and individual service components. Each component maintains its unique identity while clearly connecting to the CHORUS orchestration platform through:
|
||||
|
||||
- **Consistent Visual Language**: Shared design elements and proportions
|
||||
- **Hierarchical Relationship**: Clear parent-child brand architecture
|
||||
- **Flexible Integration**: Components work independently or combined with CHORUS
|
||||
- **Scalable Implementation**: Logos work at various sizes and contexts
|
||||
|
||||
## Component Brand Architecture
|
||||
|
||||
### Primary Integration Pattern
|
||||
**Format**: [Component Icon] + [Component Name] + "powered by CHORUS"
|
||||
- **Visual Connection**: Component icons connect to CHORUS orchestration symbol
|
||||
- **Hierarchy**: Component name primary, CHORUS attribution secondary
|
||||
- **Usage**: Marketing materials, component-specific applications
|
||||
|
||||
### Secondary Integration Pattern
|
||||
**Format**: [Component Icon] + [CHORUS Icon] + [Combined Wordmark]
|
||||
- **Visual Connection**: Icons placed side-by-side with connecting element
|
||||
- **Hierarchy**: Equal visual weight, combined functionality message
|
||||
- **Usage**: Technical documentation, integrated dashboards
|
||||
|
||||
## Individual Component Logos
|
||||
|
||||
### WHOOSH - Orchestration Engine
|
||||
|
||||
#### Visual Concept: "The Command Center"
|
||||
- **Icon Design**: Stylized orchestration podium with flowing conductor lines
|
||||
- **Metaphor**: Musical conductor's podium representing workflow orchestration
|
||||
- **Visual Elements**:
|
||||
- Geometric podium base (stability, foundation)
|
||||
- Flowing curves emanating upward (orchestration, direction)
|
||||
- Node connection points (distributed coordination)
|
||||
- Subtle gradient suggesting depth and dimension
|
||||
|
||||
#### Color Specifications
|
||||
- **Primary**: Orchestration Blue (#007AFF) with Natural Paper (#F5F5DC) accents
|
||||
- **Secondary**: Brushed Aluminum (#C0C0C0) for technical elements
|
||||
- **Monochrome**: Single color applications in brand palette
|
||||
|
||||
#### Typography Integration
|
||||
- **WHOOSH**: SF Pro Display Bold, same treatment as CHORUS
|
||||
- **Orchestration Engine**: SF Pro Text Medium, 40% size of WHOOSH
|
||||
- **Brand Connection**: "powered by CHORUS" in SF Pro Text Regular, 30% size
|
||||
|
||||
### BZZZ - P2P Agent Coordination
|
||||
|
||||
#### Visual Concept: "The Network Mesh"
|
||||
- **Icon Design**: Hexagonal mesh network pattern inspired by honeycomb structure
|
||||
- **Metaphor**: Bee hive organization representing peer-to-peer coordination
|
||||
- **Visual Elements**:
|
||||
- Interconnected hexagonal cells (network nodes)
|
||||
- Dynamic connection lines (peer communication)
|
||||
- Central hub with radiating connections (distributed coordination)
|
||||
- Slight organic curvature (natural intelligence, swarm behavior)
|
||||
|
||||
#### Color Specifications
|
||||
- **Primary**: Harmony Green (#30D158) representing growth and coordination
|
||||
- **Secondary**: Carbon Black (#000000) for connection lines
|
||||
- **Accent**: Orchestration Blue (#007AFF) for central hub highlighting
|
||||
|
||||
#### Typography Integration
|
||||
- **BZZZ**: SF Pro Display Heavy with slight letter-spacing increase for buzz effect
|
||||
- **P2P Agent Coordination**: SF Pro Text Medium, descriptive subtitle
|
||||
- **Visual Treatment**: Subtle vibration effect on hover (digital applications)
|
||||
|
||||
### SLURP - Context Curator Service
|
||||
|
||||
#### Visual Concept: "The Information Layers"
|
||||
- **Icon Design**: Stacked information layers with intelligent filtering
|
||||
- **Metaphor**: Geological strata representing hierarchical context storage
|
||||
- **Visual Elements**:
|
||||
- Multiple horizontal layers with varying opacity
|
||||
- Curved flow lines showing context curation
|
||||
- Magnifying glass element suggesting intelligent search
|
||||
- Gradient transitions between layers (context relevance)
|
||||
|
||||
#### Color Specifications
|
||||
- **Primary**: Walnut Brown gradient (#8B4513 to #A0522D) for warmth and intelligence
|
||||
- **Secondary**: Natural Paper (#F5F5DC) for information layers
|
||||
- **Accent**: Orchestration Blue (#007AFF) for search and discovery elements
|
||||
|
||||
#### Typography Integration
|
||||
- **SLURP**: SF Pro Display Semibold with subtle condensed treatment
|
||||
- **Context Curator Service**: SF Pro Text Regular, professional positioning
|
||||
- **Visual Effect**: Subtle layer animation revealing depth (digital applications)
|
||||
|
||||
### COOEE - Feedback & Learning System
|
||||
|
||||
#### Visual Concept: "The Learning Loop"
|
||||
- **Icon Design**: Circular feedback loop with learning arrows and adaptation nodes
|
||||
- **Metaphor**: Australian "cooee" call representing communication and response
|
||||
- **Visual Elements**:
|
||||
- Circular arrow path suggesting continuous learning
|
||||
- Node points representing feedback collection
|
||||
- Gradient progression showing improvement over time
|
||||
- Sound wave elements referencing the "cooee" call
|
||||
|
||||
#### Color Specifications
|
||||
- **Primary**: Resonance Amber (#FF9F0A) representing energy and learning
|
||||
- **Secondary**: Harmony Green (#30D158) for positive feedback loops
|
||||
- **Accent**: Carbon Black (#000000) for contrast and professional grounding
|
||||
|
||||
#### Typography Integration
|
||||
- **COOEE**: SF Pro Display Bold with slight wave distortion (friendly, approachable)
|
||||
- **Feedback & Learning System**: SF Pro Text Medium, descriptive and professional
|
||||
- **Audio Reference**: Subtle sound wave graphic element in extended logo
|
||||
|
||||
### Monitoring & Analytics
|
||||
|
||||
#### Visual Concept: "The Insight Dashboard"
|
||||
- **Icon Design**: Modern dashboard with real-time metrics visualization
|
||||
- **Metaphor**: Mission control dashboard representing oversight and intelligence
|
||||
- **Visual Elements**:
|
||||
- Grid-based layout suggesting organized data
|
||||
- Rising chart lines indicating performance metrics
|
||||
- Circular progress indicators for health monitoring
|
||||
- Subtle glow effects suggesting live data streams
|
||||
|
||||
#### Color Specifications
|
||||
- **Primary**: Brushed Aluminum (#C0C0C0) for precision and technology
|
||||
- **Secondary**: Orchestration Blue (#007AFF) for data visualization elements
|
||||
- **Accent**: Multiple system colors for different metric types
|
||||
|
||||
#### Typography Integration
|
||||
- **Monitoring**: SF Pro Display Medium, technical and precise
|
||||
- **Analytics**: SF Pro Text Regular, secondary positioning
|
||||
- **Data Emphasis**: Monospace font (SF Mono) for numeric displays
|
||||
|
||||
## Integration Guidelines
|
||||
|
||||
### Combined Logo Layouts
|
||||
|
||||
#### Horizontal Integration
|
||||
|
||||
[Component Icon] COMPONENT NAME → [CHORUS Icon] CHORUS
|
||||
powered by
|
||||
|
||||
- **Use Case**: Marketing materials, business cards, letterhead
|
||||
- **Spacing**: Component and CHORUS sections separated by 2x the x-height
|
||||
- **Hierarchy**: Component name 100%, CHORUS name 70%, "powered by" 40%
|
||||
|
||||
#### Vertical Integration
|
||||
|
||||
[Component Icon]
|
||||
COMPONENT NAME
|
||||
↓
|
||||
[CHORUS Icon]
|
||||
CHORUS Services
|
||||
|
||||
- **Use Case**: Vertical layouts, mobile applications, square formats
|
||||
- **Spacing**: Consistent vertical rhythm based on typography line-height
|
||||
- **Connection**: Subtle arrow or connection line between icons
|
||||
|
||||
#### Compact Integration
|
||||
|
||||
[Component Icon][CHORUS Icon] COMPONENT × CHORUS
|
||||
|
||||
- **Use Case**: Favicons, app icons, tight space applications
|
||||
- **Treatment**: Icons side-by-side with minimal separation
|
||||
- **Typography**: Single line with multiplication symbol (×) or plus (+)
|
||||
|
||||
### Color Coordination Rules
|
||||
|
||||
#### Complementary Pairing
|
||||
- **WHOOSH + CHORUS**: Blue orchestration with natural paper
|
||||
- **BZZZ + CHORUS**: Green coordination with blue orchestration
|
||||
- **SLURP + CHORUS**: Walnut brown intelligence with blue precision
|
||||
- **COOEE + CHORUS**: Amber learning with blue stability
|
||||
|
||||
#### Monochrome Applications
|
||||
- All components can be rendered in single color from brand palette
|
||||
- Maintain contrast relationships between icon and text elements
|
||||
- Use opacity variations to create hierarchy in single-color applications
|
||||
|
||||
## Usage Applications
|
||||
|
||||
### Digital Applications
|
||||
- **Website Headers**: Horizontal integration with component focus
|
||||
- **App Icons**: Compact integration or component-only versions
|
||||
- **Dashboard UI**: Icon-only versions for navigation and identification
|
||||
- **API Documentation**: Component + CHORUS technical integration
|
||||
|
||||
### Print Applications
|
||||
- **Component Brochures**: Vertical integration with detailed explanations
|
||||
- **Technical Specifications**: Monochrome versions with clear hierarchy
|
||||
- **Business Materials**: Horizontal integration maintaining brand connection
|
||||
- **Trade Show Materials**: Large format applications with full integration
|
||||
|
||||
### Marketing Applications
|
||||
- **Social Media**: Component-focused posts with CHORUS attribution
|
||||
- **Advertisements**: Component benefits highlighted with platform connection
|
||||
- **Case Studies**: Component success stories within CHORUS ecosystem
|
||||
- **Email Signatures**: Compact integration for professional communication
|
||||
|
||||
## Technical Implementation
|
||||
|
||||
### SVG Structure Template
|
||||
svg
|
||||
<svg viewBox="0 0 240 60" xmlns="http://www.w3.org/2000/svg">
|
||||
<!-- Component Icon -->
|
||||
<g id="component-icon" transform="translate(0,0)">
|
||||
<!-- Component-specific icon paths -->
|
||||
</g>
|
||||
|
||||
<!-- Connection Element -->
|
||||
<g id="connection" transform="translate(80,0)">
|
||||
<!-- Connecting line or arrow -->
|
||||
</g>
|
||||
|
||||
<!-- CHORUS Icon -->
|
||||
<g id="chorus-icon" transform="translate(160,0)">
|
||||
<!-- CHORUS orchestration symbol -->
|
||||
</g>
|
||||
|
||||
<!-- Typography -->
|
||||
<text id="component-name" x="0" y="45" class="component-text">COMPONENT</text>
|
||||
<text id="chorus-name" x="160" y="45" class="chorus-text">CHORUS</text>
|
||||
</svg>
|
||||
|
||||
|
||||
### CSS Integration Classes
|
||||
css
|
||||
.component-logo {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
gap: var(--logo-spacing, 16px);
|
||||
}
|
||||
|
||||
.component-icon {
|
||||
width: var(--icon-size, 32px);
|
||||
height: var(--icon-size, 32px);
|
||||
fill: var(--component-color);
|
||||
}
|
||||
|
||||
.chorus-icon {
|
||||
width: calc(var(--icon-size, 32px) * 0.8);
|
||||
height: calc(var(--icon-size, 32px) * 0.8);
|
||||
fill: var(--chorus-color, #007AFF);
|
||||
}
|
||||
|
||||
.component-text {
|
||||
font-family: var(--font-display);
|
||||
font-weight: 700;
|
||||
font-size: var(--text-size, 18px);
|
||||
color: var(--text-color);
|
||||
}
|
||||
|
||||
|
||||
## Brand Protection Guidelines
|
||||
|
||||
### Approved Combinations
|
||||
- Any CHORUS component may be combined with the main CHORUS brand
|
||||
- Component logos may appear independently in component-specific contexts
|
||||
- Combined logos must maintain proper spacing and hierarchy relationships
|
||||
|
||||
### Prohibited Combinations
|
||||
- Components cannot be combined with competitor brands
|
||||
- Third-party logos cannot be integrated into the CHORUS component system
|
||||
- Component icons cannot be modified or recolored outside brand palette
|
||||
- Typography treatments must remain consistent with brand specifications
|
||||
|
||||
This component logo system provides CHORUS Services with a cohesive, flexible brand architecture that supports individual component marketing while reinforcing the unified platform message.
|
||||
BIN
public/logos/horizon-gradient.png
Normal file
|
After Width: | Height: | Size: 1.3 KiB |
BIN
public/logos/logo-ring-only.png
Normal file
|
After Width: | Height: | Size: 100 KiB |
238
public/logos/logo-test.html
Normal file
@@ -0,0 +1,238 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<title>CHORUS</title>
|
||||
<style>
|
||||
body { margin: 0; overflow: hidden; background-color: #5E6367; }
|
||||
canvas { display: block; }
|
||||
</style>
|
||||
|
||||
<link rel="preconnect" href="https://fonts.googleapis.com">
|
||||
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
||||
<link href="https://fonts.googleapis.com/css2?family=Exo:ital,wght@0,100..900;1,100..900&family=Luckiest+Guy&family=Roboto:ital,wght@0,100..900;1,100..900&display=swap" rel="stylesheet">
|
||||
|
||||
<script type="importmap">
|
||||
{
|
||||
"imports": {
|
||||
"three": "https://cdn.jsdelivr.net/npm/three@0.160.0/build/three.module.js",
|
||||
"three/addons/": "https://cdn.jsdelivr.net/npm/three@0.160.0/examples/jsm/",
|
||||
"lil-gui": "https://cdn.jsdelivr.net/npm/lil-gui@0.19/+esm"
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
</head>
|
||||
<body>
|
||||
<script type="module">
|
||||
import GUI from 'lil-gui';
|
||||
|
||||
import * as THREE from 'three';
|
||||
import { GLTFLoader } from 'three/addons/loaders/GLTFLoader.js';
|
||||
import { DRACOLoader } from 'three/addons/loaders/DRACOLoader.js';
|
||||
import { CSS2DRenderer, CSS2DObject } from 'three/addons/renderers/CSS2DRenderer.js';
|
||||
|
||||
// Initialize CSS2DRenderer
|
||||
const labelRenderer = new CSS2DRenderer();
|
||||
labelRenderer.setSize(window.innerWidth, window.innerHeight);
|
||||
labelRenderer.domElement.style.position = 'absolute';
|
||||
labelRenderer.domElement.style.top = '0px';
|
||||
labelRenderer.domElement.style.pointerEvents = 'none'; // allows clicks to pass through
|
||||
document.body.appendChild(labelRenderer.domElement);
|
||||
|
||||
|
||||
// === Animation parameters ===
|
||||
const spinSpeed = 0.003; // radians per frame
|
||||
|
||||
// Animation parameters (now in an object for GUI control)
|
||||
const params = {
|
||||
spinSpeedX: 0.01, // continuous X spin
|
||||
spinSpeedY: 0.01, // continuous X spin
|
||||
spinSpeedZ: 0.1, // continuous Z spin
|
||||
lightCount: 25,
|
||||
};
|
||||
|
||||
|
||||
let scene, camera, renderer, mobius, clock;
|
||||
let baseRotationY = 0;
|
||||
|
||||
|
||||
init();
|
||||
animate();
|
||||
|
||||
function init() {
|
||||
scene = new THREE.Scene();
|
||||
|
||||
const material = new THREE.MeshPhysicalMaterial({
|
||||
color: 0xFFFFFF,
|
||||
roughness: 0.24,
|
||||
metalness: 1.0,
|
||||
clearcoat: 0.48,
|
||||
clearcoatRoughness: 0.15,
|
||||
reflectivity: 1.2,
|
||||
sheen: 0.35,
|
||||
sheenColor: new THREE.Color(0x212121),
|
||||
sheenRoughness: 0.168,
|
||||
envMapIntensity: 1,
|
||||
});
|
||||
|
||||
// Add scattered lights
|
||||
addRandomLights();
|
||||
|
||||
// Generate a synthetic cube environment
|
||||
const size = 512;
|
||||
const canvas = document.createElement('canvas');
|
||||
canvas.width = size;
|
||||
canvas.height = size;
|
||||
const ctx = canvas.getContext('2d');
|
||||
|
||||
|
||||
|
||||
// Gradient: sunset horizon (bottom warm, top cool)
|
||||
const gradient = ctx.createLinearGradient(0, 0, 0, canvas.height);
|
||||
gradient.addColorStop(0, '#001133'); // top dark blue
|
||||
gradient.addColorStop(0.4, '#223366'); // mid blue
|
||||
gradient.addColorStop(0.5, '#ff8844'); // orange near horizon
|
||||
gradient.addColorStop(0.51, '#000000'); // black horizon
|
||||
gradient.addColorStop(0.8, '#105010'); // green base
|
||||
gradient.addColorStop(1, '#000000'); // black base
|
||||
|
||||
ctx.fillStyle = gradient;
|
||||
ctx.fillRect(0, 0, canvas.width, canvas.height);
|
||||
|
||||
const texture = new THREE.CanvasTexture(canvas);
|
||||
texture.mapping = THREE.EquirectangularReflectionMapping;
|
||||
|
||||
// Apply as environment
|
||||
scene.environment = texture;
|
||||
scene.background = null; // keep transparent
|
||||
|
||||
function expandGradient(img) {
|
||||
const canvas = document.createElement('canvas');
|
||||
const w = 512, h = 256; // safe HDRI-like size
|
||||
canvas.width = w;
|
||||
canvas.height = h;
|
||||
const ctx = canvas.getContext('2d');
|
||||
|
||||
// Stretch the 1px-wide strip to fill the canvas
|
||||
ctx.drawImage(img, 0, 0, w, h);
|
||||
|
||||
return new THREE.CanvasTexture(canvas);
|
||||
}
|
||||
|
||||
const envloader = new THREE.ImageLoader();
|
||||
envloader.load('horizon-gradient.png', (image) => {
|
||||
const tex = expandGradient(image);
|
||||
tex.mapping = THREE.EquirectangularReflectionMapping;
|
||||
|
||||
// ✅ safe to feed into PMREM
|
||||
const pmrem = new THREE.PMREMGenerator(renderer);
|
||||
const envMap = pmrem.fromEquirectangular(tex).texture;
|
||||
|
||||
scene.environment = envMap;
|
||||
});
|
||||
|
||||
|
||||
|
||||
const textDiv = document.createElement('div');
|
||||
textDiv.textContent = "CHORUS";
|
||||
textDiv.style.color = "#FFFFFF";
|
||||
textDiv.style.fontSize = "96px";
|
||||
textDiv.style.fontFamily = "Exo, sans-serif";
|
||||
textDiv.style.textAlign = "left";
|
||||
|
||||
// Create CSS2DObject and position it at the origin
|
||||
const textLabel = new CSS2DObject(textDiv);
|
||||
textLabel.position.set(0, 0, 0); // exact origin
|
||||
scene.add(textLabel);
|
||||
|
||||
camera = new THREE.PerspectiveCamera(45, window.innerWidth/window.innerHeight, 0.1, 100);
|
||||
camera.position.set(0, 0, 1.8);
|
||||
camera.lookAt(0, 0, 0);
|
||||
|
||||
const light = new THREE.PointLight(0xffffff, 1.4);
|
||||
light.position.set(0, 4, 1);
|
||||
scene.add(light);
|
||||
|
||||
const bottomLight = new THREE.PointLight(0x800080, 1.2, 12); // (color, intensity, distance)
|
||||
bottomLight.position.set(0, -4, 1); // directly under the model
|
||||
scene.add(bottomLight);
|
||||
|
||||
const leftLight = new THREE.PointLight(0x808000, 1.45, 5); // (color, intensity, distance)
|
||||
leftLight.position.set(-5, 0, 4); // top left of the model
|
||||
scene.add(leftLight);
|
||||
|
||||
scene.add(new THREE.AmbientLight(0xffffff, 0.45));
|
||||
|
||||
const loader = new GLTFLoader();
|
||||
|
||||
const dracoLoader = new DRACOLoader();
|
||||
dracoLoader.setDecoderPath( 'https://www.gstatic.com/draco/v1/decoders/' );
|
||||
loader.setDRACOLoader( dracoLoader );
|
||||
loader.load(
|
||||
"./mobius-ring.glb", // ensure mobius.glb is in the same folder as this HTML
|
||||
(gltf) => {
|
||||
mobius = gltf.scene;
|
||||
mobius.traverse((child) => {
|
||||
if (child.isMesh) {
|
||||
child.material = material;
|
||||
}
|
||||
});
|
||||
scene.add(mobius);
|
||||
},
|
||||
undefined,
|
||||
(err) => console.error("Error loading model:", err)
|
||||
);
|
||||
|
||||
renderer = new THREE.WebGLRenderer({ antialias: true, alpha: true });
|
||||
renderer.setPixelRatio(window.devicePixelRatio);
|
||||
renderer.setSize(window.innerWidth, window.innerHeight);
|
||||
renderer.setClearColor(0x000000, 0); // transparent background
|
||||
document.body.appendChild(renderer.domElement);
|
||||
|
||||
clock = new THREE.Clock();
|
||||
window.addEventListener("resize", onWindowResize);
|
||||
}
|
||||
|
||||
function onWindowResize() {
|
||||
camera.aspect = window.innerWidth / window.innerHeight;
|
||||
camera.updateProjectionMatrix();
|
||||
renderer.setSize(window.innerWidth, window.innerHeight);
|
||||
labelRenderer.setSize(window.innerWidth, window.innerHeight);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
function animate() {
|
||||
requestAnimationFrame(animate);
|
||||
|
||||
if (mobius) {
|
||||
const elapsed = clock.getElapsedTime();
|
||||
|
||||
// Continuous spin
|
||||
mobius.rotation.x += params.spinSpeedX;
|
||||
mobius.rotation.y += params.spinSpeedY;
|
||||
mobius.rotation.z += params.spinSpeedZ;
|
||||
}
|
||||
|
||||
renderer.render(scene, camera);
|
||||
labelRenderer.render(scene, camera);
|
||||
}
|
||||
|
||||
function addRandomLights() {
|
||||
for (let i = 0; i < params.lightCount; i++) {
|
||||
const color = new THREE.Color().setHSL(Math.random(), 0.84, 0.9);
|
||||
const light = new THREE.PointLight(color, params.lightIntensity, params.lightDistance);
|
||||
const angle = Math.random() * Math.PI * 2;
|
||||
const height = (Math.random() - 0.5) * 4;
|
||||
const radius = 6 + Math.random() * 4;
|
||||
light.position.set(Math.cos(angle) * radius, height, Math.sin(angle) * radius);
|
||||
scene.add(light);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
261
public/logos/logo-variations-specifications.md
Normal file
@@ -0,0 +1,261 @@
|
||||
# CHORUS Services Logo Variations & Specifications
|
||||
|
||||
## Overview
|
||||
|
||||
This document provides comprehensive specifications for all CHORUS Services logo variations, ensuring consistent brand presentation across every possible application context. Each variation is optimized for specific use cases while maintaining brand integrity and recognition.
|
||||
|
||||
## Primary Logo Variations
|
||||
|
||||
### 1. Horizontal Layout (Primary)
|
||||
|
||||
#### Full Color Version
|
||||
- **Usage**: Primary logo for most applications
|
||||
- **Background**: Carbon Black (#000000) or dark backgrounds
|
||||
- **Icon Color**: Natural Paper (#F5F5DC) with Orchestration Blue (#007AFF) accent
|
||||
- **Text Color**: Natural Paper (#F5F5DC) primary, Brushed Aluminum (#C0C0C0) secondary
|
||||
- **Minimum Size**: 120px width (digital), 1.5" width (print)
|
||||
- **File Formats**: SVG (preferred), PNG (2x retina), PDF (print)
|
||||
|
||||
#### Reversed Version
|
||||
- **Usage**: Light backgrounds, print applications, high-contrast needs
|
||||
- **Background**: Natural Paper (#F5F5DC), White (#FFFFFF), or light backgrounds
|
||||
- **Icon Color**: Carbon Black (#000000) with Orchestration Blue (#007AFF) accent
|
||||
- **Text Color**: Carbon Black (#000000) primary, Walnut Brown (#8B4513) secondary
|
||||
- **Applications**: Business cards, letterhead, light-theme websites
|
||||
|
||||
### 2. Stacked Layout (Vertical)
|
||||
|
||||
#### Full Color Stacked
|
||||
- **Usage**: Square formats, mobile applications, social media
|
||||
- **Proportions**: Icon above text, centered alignment
|
||||
- **Sizing**: Icon 60% of total height, text 40% of total height
|
||||
- **Minimum Size**: 80px width (digital), 1" width (print)
|
||||
- **Aspect Ratio**: Approximately 1:1.2 (width:height)
|
||||
|
||||
#### Reversed Stacked
|
||||
- **Usage**: Light backgrounds in vertical format
|
||||
- **Color Treatment**: Same as reversed horizontal
|
||||
- **Applications**: Light-theme mobile apps, print materials with vertical layout
|
||||
|
||||
### 3. Icon-Only Variations
|
||||
|
||||
#### Primary Icon
|
||||
- **Usage**: Favicons, app icons, navigation elements, profile images
|
||||
- **Design**: Orchestration symbol only, no text
|
||||
- **Size Range**: 16px to 512px (digital), 0.25" to 4" (print)
|
||||
- **Aspect Ratio**: 1:1 (perfect square)
|
||||
- **Background Treatment**: Transparent or solid brand colors
|
||||
|
||||
#### App Icon Treatment
|
||||
- **iOS Specifications**: Rounded corners with 20% corner radius
|
||||
- **Android Specifications**: Rounded corners with 15% corner radius
|
||||
- **Background**: Solid Carbon Black (#000000) with centered icon
|
||||
- **Icon Color**: Natural Paper (#F5F5DC) with Orchestration Blue accent
|
||||
- **Required Sizes**: 16, 32, 48, 64, 128, 256, 512px
|
||||
|
||||
#### Favicon Specifications
|
||||
- **Size**: 16x16px, 32x32px, 48x48px
|
||||
- **Format**: ICO file with multiple resolutions
|
||||
- **Design**: Simplified orchestration symbol
|
||||
- **Color**: High contrast version optimized for small display
|
||||
- **Background**: Transparent
|
||||
|
||||
## Monochrome Variations
|
||||
|
||||
### 1. Black Version
|
||||
- **Color**: All elements in Carbon Black (#000000)
|
||||
- **Usage**: Single-color printing, embossing, engraving
|
||||
- **Background**: White or Natural Paper only
|
||||
- **Applications**: Letterhead, business cards, cost-effective printing
|
||||
|
||||
### 2. White Version
|
||||
- **Color**: All elements in Natural Paper (#F5F5DC) or White (#FFFFFF)
|
||||
- **Usage**: Dark backgrounds, reversed applications
|
||||
- **Applications**: Dark websites, presentations, merchandise
|
||||
|
||||
### 3. Single Brand Color
|
||||
- **Orchestration Blue**: All elements in #007AFF
|
||||
- **Usage**: Branded merchandise, promotional materials
|
||||
- **Background**: White, Natural Paper, or transparent
|
||||
- **Applications**: T-shirts, promotional items, digital watermarks
|
||||
|
||||
## Specialized Context Variations
|
||||
|
||||
### 1. Watermark Version
|
||||
- **Opacity**: 15-25% transparency
|
||||
- **Usage**: Document backgrounds, presentation slides
|
||||
- **Size**: Large format, subtle presence
|
||||
- **Color**: Single color with reduced opacity
|
||||
- **Placement**: Off-center, non-interfering with content
|
||||
|
||||
### 2. Print Newspaper/Magazine
|
||||
- **Design**: High contrast, simplified details
|
||||
- **Color**: Black only for newspaper, spot color for magazines
|
||||
- **Size**: Minimum legible size for publication standards
|
||||
- **Format**: Vector format with outlined fonts
|
||||
|
||||
### 3. Embroidery Specifications
|
||||
- **Design**: Simplified orchestration symbol
|
||||
- **Stitch Count**: Optimized for production efficiency
|
||||
- **Size Range**: 0.75" to 4" width
|
||||
- **Colors**: Maximum 3 thread colors
|
||||
- **Background**: None (direct on fabric)
|
||||
|
||||
### 4. Engraving/Etching
|
||||
- **Design**: Line art version of orchestration symbol
|
||||
- **Detail Level**: Simplified for engraving depth limitations
|
||||
- **Applications**: Awards, plaques, metal products
|
||||
- **File Format**: Vector outlines, no fills
|
||||
|
||||
## Digital-Specific Variations
|
||||
|
||||
### 1. Animated Logo (Digital Only)
|
||||
- **Animation**: Subtle orchestration symbol rotation or pulse
|
||||
- **Duration**: 2-3 seconds, smooth loop
|
||||
- **Usage**: Website loading, video intros
|
||||
- **Format**: SVG animation, GIF fallback
|
||||
- **File Size**: Optimized for web performance
|
||||
|
||||
### 2. Social Media Profile Variations
|
||||
|
||||
#### LinkedIn Profile
|
||||
- **Size**: 300x300px minimum
|
||||
- **Format**: PNG with transparent background
|
||||
- **Version**: Icon-only with high contrast
|
||||
|
||||
#### Twitter/X Profile
|
||||
- **Size**: 400x400px recommended
|
||||
- **Format**: PNG or JPG
|
||||
- **Version**: Icon-only, optimized for small display
|
||||
|
||||
#### Facebook Profile
|
||||
- **Size**: 180x180px minimum
|
||||
- **Format**: PNG recommended
|
||||
- **Version**: Icon-only or simplified horizontal
|
||||
|
||||
#### Instagram Profile
|
||||
- **Size**: 320x320px minimum
|
||||
- **Format**: PNG recommended
|
||||
- **Version**: Icon-only with brand colors
|
||||
|
||||
### 3. Email Signature Specifications
|
||||
- **Size**: 120px width maximum
|
||||
- **Format**: PNG (Retina 2x resolution)
|
||||
- **Version**: Horizontal layout preferred
|
||||
- **Linking**: Clickable link to website homepage
|
||||
- **Alt Text**: "CHORUS Services - Distributed AI Orchestration"
|
||||
|
||||
## Technical Implementation Specifications
|
||||
|
||||
### SVG Code Structure
|
||||
svg
|
||||
<svg viewBox="0 0 240 60" xmlns="http://www.w3.org/2000/svg" aria-labelledby="chorus-logo-title">
|
||||
<title id="chorus-logo-title">CHORUS Services Logo</title>
|
||||
|
||||
<!-- Orchestration Icon -->
|
||||
<g id="orchestration-icon" fill="#F5F5DC">
|
||||
<!-- Icon paths here -->
|
||||
</g>
|
||||
|
||||
<!-- Brand Typography -->
|
||||
<g id="brand-text">
|
||||
<text x="80" y="35" font-family="-apple-system, SF Pro Display" font-weight="700" font-size="24" fill="#F5F5DC">CHORUS</text>
|
||||
<text x="80" y="50" font-family="-apple-system, SF Pro Text" font-weight="400" font-size="10" fill="#C0C0C0">Services</text>
|
||||
</g>
|
||||
</svg>
|
||||
|
||||
|
||||
### CSS Implementation
|
||||
css
|
||||
.chorus-logo {
|
||||
display: inline-block;
|
||||
max-width: 100%;
|
||||
height: auto;
|
||||
}
|
||||
|
||||
.chorus-logo--horizontal {
|
||||
aspect-ratio: 4/1;
|
||||
min-width: 120px;
|
||||
}
|
||||
|
||||
.chorus-logo--stacked {
|
||||
aspect-ratio: 1/1.2;
|
||||
min-width: 80px;
|
||||
}
|
||||
|
||||
.chorus-logo--icon-only {
|
||||
aspect-ratio: 1/1;
|
||||
min-width: 32px;
|
||||
}
|
||||
|
||||
/* Responsive sizing */
|
||||
@media (max-width: 768px) {
|
||||
.chorus-logo--horizontal {
|
||||
min-width: 100px;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
### File Naming Convention
|
||||
|
||||
chorus-logo-horizontal-color.svg
|
||||
chorus-logo-horizontal-reversed.svg
|
||||
chorus-logo-stacked-color.png
|
||||
chorus-logo-icon-only-white.svg
|
||||
chorus-logo-monochrome-black.pdf
|
||||
|
||||
|
||||
## Quality Assurance Checklist
|
||||
|
||||
### Before Production
|
||||
- [ ] Logo meets minimum size requirements for intended application
|
||||
- [ ] Color contrast tested for accessibility compliance (WCAG 2.1 AA)
|
||||
- [ ] File format appropriate for intended use (vector vs. raster)
|
||||
- [ ] Resolution sufficient for intended output (72 DPI web, 300 DPI print)
|
||||
- [ ] Colors match brand specifications exactly
|
||||
- [ ] Typography rendering correctly at all sizes
|
||||
- [ ] Clear space maintained around logo
|
||||
- [ ] Alternative text or descriptions provided for accessibility
|
||||
|
||||
### After Production
|
||||
- [ ] Logo displays correctly across different devices and browsers
|
||||
- [ ] Print test completed for physical applications
|
||||
- [ ] File sizes optimized for web performance
|
||||
- [ ] Backup formats available for compatibility
|
||||
- [ ] Usage rights and approvals documented
|
||||
- [ ] Brand guidelines compliance verified
|
||||
|
||||
## Approval Process
|
||||
|
||||
### Internal Review
|
||||
1. **Brand Manager**: Visual consistency and brand compliance
|
||||
2. **Design Lead**: Technical quality and implementation feasibility
|
||||
3. **Marketing Director**: Strategic alignment and marketing effectiveness
|
||||
4. **Legal Review**: Trademark compliance and usage rights
|
||||
|
||||
### External Applications
|
||||
1. **Partner Usage**: Requires brand license agreement and approval
|
||||
2. **Media Usage**: Provide official logo package with usage guidelines
|
||||
3. **Vendor Applications**: Review and approve before production
|
||||
4. **International Usage**: Cultural sensitivity review when applicable
|
||||
|
||||
## Logo Package Contents
|
||||
|
||||
### Standard Logo Package
|
||||
- Horizontal color version (SVG, PNG 2x, PDF)
|
||||
- Horizontal reversed version (SVG, PNG 2x, PDF)
|
||||
- Stacked color version (SVG, PNG 2x)
|
||||
- Icon-only versions (SVG, PNG 2x, ICO)
|
||||
- Monochrome versions (SVG, PNG, PDF)
|
||||
- Usage guidelines summary (PDF)
|
||||
|
||||
### Extended Logo Package
|
||||
- All standard package contents
|
||||
- Animated versions (SVG, GIF)
|
||||
- Social media optimized versions
|
||||
- Print-specific versions (high-resolution)
|
||||
- Component integration examples
|
||||
- Brand color swatches (ASE, ACO, CSS)
|
||||
- Typography files and licenses
|
||||
|
||||
This comprehensive logo variation system ensures CHORUS Services maintains consistent, professional brand presentation across every possible application while providing the flexibility needed for diverse marketing and communication contexts.
|
||||
245
public/logos/logo.html
Normal file
@@ -0,0 +1,245 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<title>CHORUS Möbius Strip</title>
|
||||
<style>
|
||||
body { margin: 0; overflow: hidden; background-color: #0b0213; }
|
||||
canvas { display: block; }
|
||||
</style>
|
||||
|
||||
<link rel="preconnect" href="https://fonts.googleapis.com">
|
||||
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
||||
<link href="https://fonts.googleapis.com/css2?family=Exo:ital,wght@0,100..900;1,100..900&family=Luckiest+Guy&family=Roboto:ital,wght@0,100..900;1,100..900&display=swap" rel="stylesheet">
|
||||
|
||||
<script type="importmap">
|
||||
{
|
||||
"imports": {
|
||||
"three": "https://cdn.jsdelivr.net/npm/three@0.160.0/build/three.module.js",
|
||||
"three/addons/": "https://cdn.jsdelivr.net/npm/three@0.160.0/examples/jsm/",
|
||||
"lil-gui": "https://cdn.jsdelivr.net/npm/lil-gui@0.19/+esm"
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
</head>
|
||||
<body>
|
||||
<script type="module">
|
||||
import GUI from 'lil-gui';
|
||||
|
||||
import * as THREE from 'three';
|
||||
import { GLTFLoader } from 'three/addons/loaders/GLTFLoader.js';
|
||||
import { DRACOLoader } from 'three/addons/loaders/DRACOLoader.js';
|
||||
import { CSS2DRenderer, CSS2DObject } from 'three/addons/renderers/CSS2DRenderer.js';
|
||||
|
||||
// Initialize CSS2DRenderer
|
||||
const labelRenderer = new CSS2DRenderer();
|
||||
labelRenderer.setSize(window.innerWidth, window.innerHeight);
|
||||
labelRenderer.domElement.style.position = 'absolute';
|
||||
labelRenderer.domElement.style.top = '0px';
|
||||
labelRenderer.domElement.style.pointerEvents = 'none'; // allows clicks to pass through
|
||||
document.body.appendChild(labelRenderer.domElement);
|
||||
|
||||
|
||||
// === Animation parameters ===
|
||||
const spinSpeed = 0.003; // radians per frame
|
||||
|
||||
// Animation parameters (now in an object for GUI control)
|
||||
const params = {
|
||||
spinSpeedX: 0.010, // continuous X spin
|
||||
spinSpeedY: -0.010, // continuous X spin
|
||||
spinSpeedZ: -0.1, // continuous Z spin
|
||||
lightCount: 25,
|
||||
};
|
||||
|
||||
|
||||
let scene, camera, renderer, mobius, clock;
|
||||
let baseRotationY = 0;
|
||||
|
||||
// Setup lil-gui
|
||||
|
||||
// const gui = new GUI();
|
||||
// gui.add(params, 'spinSpeedX', -0.2, 0.2).step(0.001).name('X Spin Speed');
|
||||
// gui.add(params, 'spinSpeedY', -0.2, 0.2).step(0.001).name('Y Spin Speed');
|
||||
// gui.add(params, 'spinSpeedZ', -0.2, 0.2).step(0.001).name('Z Spin Speed');
|
||||
|
||||
|
||||
init();
|
||||
animate();
|
||||
|
||||
function init() {
|
||||
scene = new THREE.Scene();
|
||||
|
||||
const material = new THREE.MeshPhysicalMaterial({
|
||||
color: 0x333333,
|
||||
roughness: 0.24,
|
||||
metalness: 1.0,
|
||||
clearcoat: 0.48,
|
||||
clearcoatRoughness: 0.15,
|
||||
reflectivity: 1.2,
|
||||
sheen: 0.35,
|
||||
sheenColor: new THREE.Color(0x212121),
|
||||
sheenRoughness: 0.168,
|
||||
envMapIntensity: 1,
|
||||
});
|
||||
|
||||
// Add scattered lights
|
||||
addRandomLights();
|
||||
|
||||
// Generate a synthetic cube environment
|
||||
const size = 512;
|
||||
const canvas = document.createElement('canvas');
|
||||
canvas.width = size;
|
||||
canvas.height = size;
|
||||
const ctx = canvas.getContext('2d');
|
||||
|
||||
|
||||
|
||||
// Gradient: sunset horizon (bottom warm, top cool)
|
||||
const gradient = ctx.createLinearGradient(0, 0, 0, canvas.height);
|
||||
gradient.addColorStop(0, '#001133'); // top dark blue
|
||||
gradient.addColorStop(0.4, '#223366'); // mid blue
|
||||
gradient.addColorStop(0.5, '#ff8844'); // orange near horizon
|
||||
gradient.addColorStop(0.51, '#000000'); // black horizon
|
||||
gradient.addColorStop(0.8, '#105010'); // green base
|
||||
gradient.addColorStop(1, '#000000'); // black base
|
||||
|
||||
ctx.fillStyle = gradient;
|
||||
ctx.fillRect(0, 0, canvas.width, canvas.height);
|
||||
|
||||
const texture = new THREE.CanvasTexture(canvas);
|
||||
texture.mapping = THREE.EquirectangularReflectionMapping;
|
||||
|
||||
// Apply as environment
|
||||
scene.environment = texture;
|
||||
scene.background = null; // keep transparent
|
||||
|
||||
function expandGradient(img) {
|
||||
const canvas = document.createElement('canvas');
|
||||
const w = 512, h = 256; // safe HDRI-like size
|
||||
canvas.width = w;
|
||||
canvas.height = h;
|
||||
const ctx = canvas.getContext('2d');
|
||||
|
||||
// Stretch the 1px-wide strip to fill the canvas
|
||||
ctx.drawImage(img, 0, 0, w, h);
|
||||
|
||||
return new THREE.CanvasTexture(canvas);
|
||||
}
|
||||
|
||||
const envloader = new THREE.ImageLoader();
|
||||
envloader.load('horizon-gradient.png', (image) => {
|
||||
const tex = expandGradient(image);
|
||||
tex.mapping = THREE.EquirectangularReflectionMapping;
|
||||
|
||||
// ✅ safe to feed into PMREM
|
||||
const pmrem = new THREE.PMREMGenerator(renderer);
|
||||
const envMap = pmrem.fromEquirectangular(tex).texture;
|
||||
|
||||
scene.environment = envMap;
|
||||
});
|
||||
|
||||
|
||||
|
||||
const textDiv = document.createElement('div');
|
||||
textDiv.textContent = "CHORUS";
|
||||
textDiv.style.color = "#ffffff";
|
||||
textDiv.style.fontSize = "96px";
|
||||
textDiv.style.fontFamily = "Exo, sans-serif";
|
||||
textDiv.style.textAlign = "center";
|
||||
|
||||
// Create CSS2DObject and position it at the origin
|
||||
const textLabel = new CSS2DObject(textDiv);
|
||||
textLabel.position.set(0, 0, 0); // exact origin
|
||||
scene.add(textLabel);
|
||||
|
||||
camera = new THREE.PerspectiveCamera(45, window.innerWidth/window.innerHeight, 0.1, 100);
|
||||
camera.position.set(0, 0, 1.8);
|
||||
camera.lookAt(0, 0, 0);
|
||||
|
||||
const light = new THREE.PointLight(0xffffff, 1.4);
|
||||
light.position.set(0, 4, 1);
|
||||
scene.add(light);
|
||||
|
||||
const bottomLight = new THREE.PointLight(0x800080, 1.2, 12); // (color, intensity, distance)
|
||||
bottomLight.position.set(0, -4, 1); // directly under the model
|
||||
scene.add(bottomLight);
|
||||
|
||||
const leftLight = new THREE.PointLight(0x808000, 1.45, 5); // (color, intensity, distance)
|
||||
leftLight.position.set(-5, 0, 4); // top left of the model
|
||||
scene.add(leftLight);
|
||||
|
||||
scene.add(new THREE.AmbientLight(0xffffff, 0.45));
|
||||
|
||||
const loader = new GLTFLoader();
|
||||
|
||||
const dracoLoader = new DRACOLoader();
|
||||
dracoLoader.setDecoderPath( 'https://www.gstatic.com/draco/v1/decoders/' );
|
||||
loader.setDRACOLoader( dracoLoader );
|
||||
loader.load(
|
||||
"./mobius-ring.glb", // ensure mobius.glb is in the same folder as this HTML
|
||||
(gltf) => {
|
||||
mobius = gltf.scene;
|
||||
mobius.traverse((child) => {
|
||||
if (child.isMesh) {
|
||||
child.material = material;
|
||||
}
|
||||
});
|
||||
scene.add(mobius);
|
||||
},
|
||||
undefined,
|
||||
(err) => console.error("Error loading model:", err)
|
||||
);
|
||||
|
||||
renderer = new THREE.WebGLRenderer({ antialias: true, alpha: true });
|
||||
renderer.setPixelRatio(window.devicePixelRatio);
|
||||
renderer.setSize(window.innerWidth, window.innerHeight);
|
||||
renderer.setClearColor(0x000000, 0); // transparent background
|
||||
document.body.appendChild(renderer.domElement);
|
||||
|
||||
clock = new THREE.Clock();
|
||||
window.addEventListener("resize", onWindowResize);
|
||||
}
|
||||
|
||||
function onWindowResize() {
|
||||
camera.aspect = window.innerWidth / window.innerHeight;
|
||||
camera.updateProjectionMatrix();
|
||||
renderer.setSize(window.innerWidth, window.innerHeight);
|
||||
labelRenderer.setSize(window.innerWidth, window.innerHeight);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
function animate() {
|
||||
requestAnimationFrame(animate);
|
||||
|
||||
if (mobius) {
|
||||
const elapsed = clock.getElapsedTime();
|
||||
|
||||
// Continuous spin
|
||||
mobius.rotation.x += params.spinSpeedX;
|
||||
mobius.rotation.y += params.spinSpeedY;
|
||||
mobius.rotation.z += params.spinSpeedZ;
|
||||
}
|
||||
|
||||
renderer.render(scene, camera);
|
||||
labelRenderer.render(scene, camera);
|
||||
}
|
||||
|
||||
function addRandomLights() {
|
||||
for (let i = 0; i < params.lightCount; i++) {
|
||||
const color = new THREE.Color().setHSL(Math.random(), 0.84, 0.9);
|
||||
const light = new THREE.PointLight(color, params.lightIntensity, params.lightDistance);
|
||||
const angle = Math.random() * Math.PI * 2;
|
||||
const height = (Math.random() - 0.5) * 4;
|
||||
const radius = 6 + Math.random() * 4;
|
||||
light.position.set(Math.cos(angle) * radius, height, Math.sin(angle) * radius);
|
||||
scene.add(light);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
BIN
public/logos/logo.png
Normal file
|
After Width: | Height: | Size: 126 KiB |
BIN
public/logos/mobius-ring.blend
Normal file
BIN
public/logos/mobius-ring.glb
Normal file
BIN
public/logos/moebius-ring.blend
Normal file
58
scheduled/README.md
Normal file
@@ -0,0 +1,58 @@
|
||||
# Scheduled Posts
|
||||
|
||||
This directory contains blog posts that are scheduled for future publication.
|
||||
|
||||
## Directory Structure
|
||||
|
||||
```
|
||||
scheduled/
|
||||
├── 2024/
|
||||
│ ├── 01/
|
||||
│ ├── 02/
|
||||
│ └── ...
|
||||
├── 2025/
|
||||
│ ├── 01/
|
||||
│ ├── 02/
|
||||
│ └── ...
|
||||
└── README.md
|
||||
```
|
||||
|
||||
## File Naming Convention
|
||||
|
||||
Posts should be named with the format: `YYYY-MM-DD-slug.md`
|
||||
|
||||
Example: `2024-03-15-understanding-ai-agents.md`
|
||||
|
||||
## Frontmatter Format
|
||||
|
||||
Each scheduled post should include the following frontmatter:
|
||||
|
||||
```yaml
|
||||
---
|
||||
title: "Your Post Title"
|
||||
description: "Brief description of the post"
|
||||
date: "2024-03-15"
|
||||
publishDate: "2024-03-15T09:00:00.000Z"
|
||||
author:
|
||||
name: "Author Name"
|
||||
role: "Author Role"
|
||||
tags:
|
||||
- "tag1"
|
||||
- "tag2"
|
||||
featured: false
|
||||
draft: false
|
||||
---
|
||||
```
|
||||
|
||||
## Publishing Process
|
||||
|
||||
1. Write your post in the appropriate scheduled directory
|
||||
2. Set the `publishDate` to when you want it published
|
||||
3. A scheduled job will move posts from `scheduled/` to `posts/` when their publish date arrives
|
||||
4. The blog will automatically pick up the new post and display it
|
||||
|
||||
## Notes
|
||||
|
||||
- Posts in this directory are not visible on the live blog until moved to `posts/`
|
||||
- Use `draft: true` for posts that are work-in-progress
|
||||
- The `publishDate` field determines when the post goes live
|
||||
268
tailwind.config.js
Normal file
@@ -0,0 +1,268 @@
|
||||
/** @type {import('tailwindcss').Config} */
|
||||
module.exports = {
|
||||
content: [
|
||||
'./pages/**/*.{js,ts,jsx,tsx,mdx}',
|
||||
'./components/**/*.{js,ts,jsx,tsx,mdx}',
|
||||
'./app/**/*.{js,ts,jsx,tsx,mdx}',
|
||||
],
|
||||
darkMode: 'class',
|
||||
theme: {
|
||||
extend: {
|
||||
colors: {
|
||||
// Core Brand Colors
|
||||
'carbon': {
|
||||
950: '#000000',
|
||||
900: '#0a0a0a',
|
||||
800: '#1a1a1a',
|
||||
700: '#2a2a2a',
|
||||
600: '#666666',
|
||||
500: '#808080',
|
||||
400: '#a0a0a0',
|
||||
300: '#c0c0c0',
|
||||
200: '#e0e0e0',
|
||||
100: '#f0f0f0',
|
||||
50: '#f8f8f8'
|
||||
},
|
||||
'mulberry': {
|
||||
950: '#0b0213',
|
||||
900: '#1a1426',
|
||||
800: '#2a2639',
|
||||
700: '#3a384c',
|
||||
600: '#4a4a5f',
|
||||
500: '#5a5c72',
|
||||
400: '#7a7e95',
|
||||
300: '#9aa0b8',
|
||||
200: '#bac2db',
|
||||
100: '#dae4fe',
|
||||
50: '#f0f4ff'
|
||||
},
|
||||
'walnut': {
|
||||
950: '#1E1815',
|
||||
900: '#403730',
|
||||
800: '#504743',
|
||||
700: '#605756',
|
||||
600: '#706769',
|
||||
500: '#80777c',
|
||||
400: '#90878f',
|
||||
300: '#a09aa2',
|
||||
200: '#b0adb5',
|
||||
100: '#c0c0c8',
|
||||
50: '#d0d3db',
|
||||
25: '#e0e6ee'
|
||||
},
|
||||
'nickel': {
|
||||
950: '#171717',
|
||||
900: '#2a2a2a',
|
||||
800: '#3d3d3d',
|
||||
700: '#505050',
|
||||
600: '#636363',
|
||||
500: '#767676',
|
||||
400: '#c1bfb1',
|
||||
300: '#d4d2c6',
|
||||
200: '#e7e5db',
|
||||
100: '#faf8f0',
|
||||
50: '#fdfcf8'
|
||||
},
|
||||
// System Colors
|
||||
'ocean': {
|
||||
950: '#2a3441',
|
||||
900: '#3a4654',
|
||||
800: '#4a5867',
|
||||
700: '#5a6c80',
|
||||
600: '#6a7e99',
|
||||
500: '#7a90b2',
|
||||
400: '#8ba3c4',
|
||||
300: '#9bb6d6',
|
||||
200: '#abc9e8',
|
||||
100: '#bbdcfa',
|
||||
50: '#cbefff'
|
||||
},
|
||||
'eucalyptus': {
|
||||
950: '#2a3330',
|
||||
900: '#3a4540',
|
||||
800: '#4a5750',
|
||||
700: '#515d54',
|
||||
600: '#5a6964',
|
||||
500: '#6a7974',
|
||||
400: '#7a8a7f',
|
||||
300: '#8a9b8f',
|
||||
200: '#9aac9f',
|
||||
100: '#aabdaf',
|
||||
50: '#bacfbf'
|
||||
},
|
||||
'sand': {
|
||||
950: '#8E7B5E',
|
||||
900: '#99886E',
|
||||
800: '#A4957E',
|
||||
700: '#AFA28E',
|
||||
600: '#BAAF9F',
|
||||
500: '#C5BCAF',
|
||||
400: '#D0C9BF',
|
||||
300: '#DBD6CF',
|
||||
200: '#E6E3DF',
|
||||
100: '#F1F0EF',
|
||||
50: '#F1F0EF',
|
||||
},
|
||||
'coral': {
|
||||
950: '#6A4A48',
|
||||
900: '#7B5D5A',
|
||||
800: '#8C706C',
|
||||
700: '#9D8380',
|
||||
600: '#AE9693',
|
||||
500: '#BFAAA7',
|
||||
400: '#D0BDBB',
|
||||
300: '#E1D1CF',
|
||||
200: '#F2E4E3',
|
||||
100: '#9e979c',
|
||||
50: '#aea7ac'
|
||||
}
|
||||
},
|
||||
fontFamily: {
|
||||
sans: ['var(--font-inter)', 'Inter Tight', 'Inter', 'system-ui', 'sans-serif'],
|
||||
mono: ['Inconsolata', 'ui-monospace', 'monospace'],
|
||||
logo: ['var(--font-exo)', 'Exo', 'Inter Tight', 'sans-serif']
|
||||
},
|
||||
spacing: {
|
||||
'chorus-xxs': '0.854rem',
|
||||
'chorus-xs': '0.945rem',
|
||||
'chorus-sm': '1.0rem',
|
||||
'chorus-base': '1.25rem',
|
||||
'chorus-md': '1.953rem',
|
||||
'chorus-lg': '2.441rem',
|
||||
'chorus-xl': '3.052rem',
|
||||
'chorus-xxl': '6.1rem',
|
||||
},
|
||||
fontSize: {
|
||||
'xs': ['0.854rem', { lineHeight: '1.00rem', fontWeight: '600' }],
|
||||
'sm': ['0.954rem', { lineHeight: '1.10rem', fontWeight: '500' }],
|
||||
'base': ['1rem', { lineHeight: '1.50rem', fontWeight: '400' }],
|
||||
'lg': ['1.25rem', { lineHeight: '1.75rem', fontWeight: '400' }],
|
||||
'xl': ['1.563rem', { lineHeight: '2.00rem', fontWeight: '400' }],
|
||||
'2xl': ['1.953rem', { lineHeight: '2.50rem', fontWeight: '300' }],
|
||||
'3xl': ['2.441rem', { lineHeight: '3.00rem', fontWeight: '200' }],
|
||||
'4xl': ['3.052rem', { lineHeight: '3.50rem', fontWeight: '100' }],
|
||||
'5xl': ['3.815rem', { lineHeight: '4.00rem', fontWeight: '100' }],
|
||||
'h7': ['1.000rem', { lineHeight: '1.25rem', fontWeight: '400' }],
|
||||
'h6': ['1.250rem', { lineHeight: '1.563rem', fontWeight: '500' }],
|
||||
'h5': ['1.563rem', { lineHeight: '1.953rem', fontWeight: '500' }],
|
||||
'h4': ['1.953rem', { lineHeight: '2.441rem', fontWeight: '600' }],
|
||||
'h3': ['2.441rem', { lineHeight: '3.052rem', fontWeight: '600' }],
|
||||
'h2': ['3.052rem', { lineHeight: '4.768rem', fontWeight: '700' }],
|
||||
'h1': ['4.768rem', { lineHeight: '6.96rem', fontWeight: '100' }],
|
||||
'display-sm': ['3.815rem', { lineHeight: '4rem', fontWeight: '800' }],
|
||||
'display-md': ['4.768rem', { lineHeight: '5rem', fontWeight: '800' }],
|
||||
'display-lg': ['5.96rem', { lineHeight: '6rem', fontWeight: '800' }],
|
||||
},
|
||||
width: {
|
||||
'rem-xs': '0.640rem',
|
||||
'rem-sm': '0.800rem',
|
||||
'rem-base': '1.000rem',
|
||||
'rem-lg': '1.250rem',
|
||||
'rem-xl': '1.563rem',
|
||||
'rem-2xl': '1.953rem',
|
||||
'rem-3xl': '2.441rem',
|
||||
'rem-4xl': '3.052rem',
|
||||
'rem-5xl': '3.815rem',
|
||||
},
|
||||
height: {
|
||||
'rem-xs': '0.640rem',
|
||||
'rem-sm': '0.800rem',
|
||||
'rem-base': '1.000rem',
|
||||
'rem-lg': '1.250rem',
|
||||
'rem-xl': '1.563rem',
|
||||
'rem-2xl': '1.953rem',
|
||||
'rem-3xl': '2.441rem',
|
||||
'rem-4xl': '3.052rem',
|
||||
'rem-5xl': '3.815rem',
|
||||
},
|
||||
borderRadius: {
|
||||
'none': '0',
|
||||
'micro': '0.125rem',
|
||||
'sm': '0.25rem',
|
||||
'base': '0.375rem',
|
||||
'md': '0.5rem',
|
||||
'lg': '0.75rem',
|
||||
'xl': '1rem',
|
||||
'full': '9999px',
|
||||
},
|
||||
animation: {
|
||||
'fade-in': 'fadeIn 0.6s ease-out',
|
||||
'slide-up': 'slideUp 0.8s ease-out',
|
||||
'mobius-rotate': 'mobiusRotate 20s linear infinite',
|
||||
},
|
||||
keyframes: {
|
||||
fadeIn: {
|
||||
'0%': { opacity: '0' },
|
||||
'100%': { opacity: '1' },
|
||||
},
|
||||
slideUp: {
|
||||
'0%': { opacity: '0', transform: 'translateY(2rem)' },
|
||||
'100%': { opacity: '1', transform: 'translateY(0)' },
|
||||
},
|
||||
mobiusRotate: {
|
||||
'0%': { transform: 'rotateY(0deg) rotateX(10deg)' },
|
||||
'100%': { transform: 'rotateY(360deg) rotateX(10deg)' },
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
plugins: [
|
||||
require('@tailwindcss/typography'),
|
||||
function({ addUtilities }) {
|
||||
addUtilities({
|
||||
// H7 Utility Class
|
||||
'.h7': {
|
||||
fontSize: '0.8rem',
|
||||
lineHeight: '1.25rem',
|
||||
fontWeight: '700',
|
||||
letterSpacing: '0.05em',
|
||||
textTransform: 'uppercase'
|
||||
},
|
||||
|
||||
// Complete H1-H7 Typography Utilities
|
||||
'.text-h1': {
|
||||
fontSize: '4.768rem',
|
||||
lineHeight: '6.96rem',
|
||||
fontWeight: '100',
|
||||
fontFamily: 'var(--font-inter), Inter Tight, sans-serif'
|
||||
},
|
||||
'.text-h2': {
|
||||
fontSize: '3.052rem',
|
||||
lineHeight: '4.768rem',
|
||||
fontWeight: '700',
|
||||
fontFamily: 'var(--font-exo), Exo, Inter Tight, sans-serif'
|
||||
},
|
||||
'.text-h3': {
|
||||
fontSize: '2.441rem',
|
||||
lineHeight: '3.052rem',
|
||||
fontWeight: '600',
|
||||
fontFamily: 'var(--font-inter), Inter Tight, sans-serif'
|
||||
},
|
||||
'.text-h4': {
|
||||
fontSize: '1.953rem',
|
||||
lineHeight: '2.441rem',
|
||||
fontWeight: '600',
|
||||
fontFamily: 'var(--font-inter), Inter Tight, sans-serif'
|
||||
},
|
||||
'.text-h5': {
|
||||
fontSize: '1.563rem',
|
||||
lineHeight: '1.953rem',
|
||||
fontWeight: '500',
|
||||
fontFamily: 'var(--font-inter), Inter Tight, sans-serif'
|
||||
},
|
||||
'.text-h6': {
|
||||
fontSize: '1.250rem',
|
||||
lineHeight: '1.563rem',
|
||||
fontWeight: '500',
|
||||
fontFamily: 'var(--font-inter), Inter Tight, sans-serif'
|
||||
},
|
||||
'.text-h7': {
|
||||
fontSize: '1.000rem',
|
||||
lineHeight: '1.25rem',
|
||||
fontWeight: '400',
|
||||
fontFamily: 'var(--font-inter), Inter Tight, sans-serif'
|
||||
}
|
||||
})
|
||||
}
|
||||
],
|
||||
}
|
||||
28
tsconfig.json
Normal file
@@ -0,0 +1,28 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"target": "es5",
|
||||
"lib": ["dom", "dom.iterable", "es6"],
|
||||
"allowJs": true,
|
||||
"skipLibCheck": true,
|
||||
"strict": true,
|
||||
"noEmit": true,
|
||||
"esModuleInterop": true,
|
||||
"module": "esnext",
|
||||
"moduleResolution": "bundler",
|
||||
"resolveJsonModule": true,
|
||||
"isolatedModules": true,
|
||||
"jsx": "preserve",
|
||||
"incremental": true,
|
||||
"plugins": [
|
||||
{
|
||||
"name": "next"
|
||||
}
|
||||
],
|
||||
"baseUrl": ".",
|
||||
"paths": {
|
||||
"@/*": ["./*"]
|
||||
}
|
||||
},
|
||||
"include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", ".next/types/**/*.ts"],
|
||||
"exclude": ["node_modules"]
|
||||
}
|
||||
30
types/blog.ts
Normal file
@@ -0,0 +1,30 @@
|
||||
export interface BlogPost {
|
||||
slug: string
|
||||
title: string
|
||||
description: string
|
||||
content: string
|
||||
date: string
|
||||
author: {
|
||||
name: string
|
||||
avatar?: string
|
||||
role?: string
|
||||
}
|
||||
tags: string[]
|
||||
featured?: boolean
|
||||
coverImage?: string
|
||||
readingTime: number
|
||||
}
|
||||
|
||||
export interface BlogMeta {
|
||||
title: string
|
||||
description: string
|
||||
date: string
|
||||
author: {
|
||||
name: string
|
||||
avatar?: string
|
||||
role?: string
|
||||
}
|
||||
tags: string[]
|
||||
featured?: boolean
|
||||
coverImage?: string
|
||||
}
|
||||