Init project

This commit is contained in:
Oleg Proskurin 2025-09-13 23:02:51 +07:00
commit 692ee4fa32
1184 changed files with 730016 additions and 0 deletions

View File

@ -0,0 +1,70 @@
---
description: Generate a professional image using Gemini Flash via Nano Banana MCP from free-form description
argument-hint: <description>
allowed-tools: [Read, Write, Glob, Grep, Bash, mcp__nano-banana-mcp__generate_image, mcp__nano-banana-mcp__get_configuration_status]
---
Generate a professional image based on the user description: "$ARGUMENTS"
Follow these steps:
1. **Configuration Check**: First verify that Gemini API is properly configured using `mcp__nano-banana-mcp__get_configuration_status`
2. **Context Discovery**: Automatically search for and gather relevant context from the project files:
- Search for any mentioned characters in `/heroes/` directory
- Look for locations in `/locations/` or `/cities/` directories
- Find world information in `/worlds/` directory
- Identify items in `/items/` directory
- Check for creatures in `/creatures/` directory
- Find applicable settings in `/settings/` directory
3. **Entity Analysis**: Parse the description to identify:
- Characters mentioned (explicit or implied)
- Locations referenced
- Items involved
- Creatures present
- Scene context and actions
- Appropriate style settings to apply
4. **Prompt Generation**: Create a professional prompt following the guidelines in `@docs/prompting-guide.md`:
- Use narrative descriptions instead of keyword lists
- Apply appropriate template from the prompting guide based on content type
- Include world-specific style elements
- Reference character unique identifying features
- Integrate linked items and relationships naturally
- Specify lighting and atmosphere
- Include technical quality descriptors
- Maintain visual continuity with established universe
5. **Settings Integration**: Automatically apply appropriate settings based on context:
- Character clothing based on status, world, and scenario
- Transportation methods suitable for world and character
- Environmental styles matching location and world
- Weapon styles appropriate for character and scenario
- Magical effects suitable for character abilities
6. **Image Generation**: Use `mcp__nano-banana-mcp__generate_image` with the professionally crafted prompt
7. **File Management**: Upon successful generation:
- Save image to appropriate directory based on content:
- Character portraits → `/heroes/{character-name}/photos/`
- Location shots → `/locations/{location-name}/images/` or `/cities/{city-name}/images/`
- Item visualizations → `/items/{item-name}/images/`
- Creature images → `/creatures/{creature-name}/images/`
- Scene compositions → `/scenes/{scene-name}/images/`
- Archive the successful prompt in corresponding `/prompts/` directory
- Update cross-references if new relationships are established
8. **Documentation**: Create a markdown file in `/prepared_prompts/` directory documenting:
- The final prompt used
- Applied settings and context
- Generated image path
- Validation results and suggestions
- Entity relationships discovered
**Important**:
- The prompt must be in English regardless of input language
- Follow exact templates and best practices from `docs/prompting-guide.md`
- Respect the project framework defined in `CLAUDE.md`
- Use `mcp__nano-banana-mcp__generate_image` tool for actual image generation
- Ensure proper file organization according to project structure

View File

@ -0,0 +1,60 @@
---
description: Generate a professional Gemini Flash Image prompt from free-form description
argument-hint: <description>
allowed-tools: [Read, Write, Glob, Grep, Bash]
---
Create a professional image generation prompt based on the user description: "$ARGUMENTS"
Follow these steps:
1. **Context Discovery**: Automatically search for and gather relevant context from the project files:
- Search for any mentioned characters in `/heroes/` directory
- Look for locations in `/locations/` or `/cities/` directories
- Find world information in `/worlds/` directory
- Identify items in `/items/` directory
- Check for creatures in `/creatures/` directory
- Find applicable settings in `/settings/` directory
2. **Entity Analysis**: Parse the description to identify:
- Characters mentioned (explicit or implied)
- Locations referenced
- Items involved
- Creatures present
- Scene context and actions
- Appropriate style settings to apply
3. **Prompt Generation**: Create a professional prompt following the guidelines in `@docs/prompting-guide.md`:
- Use narrative descriptions instead of keyword lists
- Apply appropriate template from the prompting guide based on content type
- Include world-specific style elements
- Reference character unique identifying features
- Integrate linked items and relationships naturally
- Specify lighting and atmosphere
- Include technical quality descriptors
- Maintain visual continuity with established universe
4. **Settings Integration**: Automatically apply appropriate settings based on context:
- Character clothing based on status, world, and scenario
- Transportation methods suitable for world and character
- Environmental styles matching location and world
- Weapon styles appropriate for character and scenario
- Magical effects suitable for character abilities
5. **Reference Images**: If the prompt requires reference images, include their file paths in markdown format.
6. **Validation**: Check the generated prompt against best practices:
- Ensure narrative structure (not keyword lists)
- Include lighting and atmosphere descriptions
- Specify technical quality requirements
- Maintain consistency with established character/location features
- Follow appropriate template from prompting guide
7. **Output**: Save the final prompt as a markdown file in `/prepared_prompts/` directory with:
- Timestamp and description in filename
- Complete prompt ready for Gemini 2.5 Flash Image
- Applied settings documentation
- Reference image paths if needed
- Validation results and suggestions
**Important**: The output must be in English regardless of input language. Follow the exact templates and best practices from `docs/prompting-guide.md` and respect the project framework defined in `CLAUDE.md`.

View File

@ -0,0 +1,87 @@
---
description: Edit/update an existing image using Gemini Flash via Nano Banana MCP with professional prompting
argument-hint: <image_path> <edit_description>
allowed-tools: [Read, Write, Glob, Grep, Bash, mcp__nano-banana-mcp__edit_image, mcp__nano-banana-mcp__continue_editing, mcp__nano-banana-mcp__get_last_image_info, mcp__nano-banana-mcp__get_configuration_status]
---
Edit/update an existing image based on the provided image path and edit description.
**Usage**: `/update <image_path> <edit_description>`
**Example**: `/update /heroes/camelot/photos/portrait.jpg add a mystical staff in his hand`
Follow these steps:
1. **Configuration Check**: First verify that Gemini API is properly configured using `mcp__nano-banana-mcp__get_configuration_status`
2. **Image Path Validation**:
- Parse the first argument as the image path
- Verify the image file exists and is accessible
- Extract the remaining arguments as the edit description
- If no image path provided, check if there's a recent image using `mcp__nano-banana-mcp__get_last_image_info`
3. **Context Discovery**: Based on the image location and edit description, gather relevant context:
- If image is in `/heroes/` directory, load character description
- If in `/locations/` or `/cities/`, load location context
- If in `/items/`, load item specifications
- If in `/creatures/`, load creature details
- Search for applicable settings in `/settings/` directory
- Load world information from `/worlds/` directory if applicable
4. **Entity Analysis**: Parse the edit description to identify:
- Changes requested (add, remove, modify elements)
- New elements to be introduced
- Style preferences or requirements
- Lighting or mood adjustments
- Technical specifications needed
5. **Edit Prompt Generation**: Create a professional edit prompt following `@docs/prompting-guide.md` editing templates:
- **Adding/Removing Elements**: "Using the provided image of [subject], please [add/remove/modify] [element] to/from the scene. Ensure the change is [integration description]."
- **Inpainting**: "Using the provided image, change only the [specific element] to [new element]. Keep everything else exactly the same, preserving the original style, lighting, and composition."
- **Style Transfer**: "Transform the provided image into [artistic style]. Preserve the original composition but render it with [stylistic elements]."
- **Detail Preservation**: "Using the provided image, [edit request]. Ensure that [critical details] remain completely unchanged. The modification should [integration requirements]."
6. **Settings Integration**: Apply appropriate settings for consistency:
- Maintain character clothing styles if character is present
- Preserve world-specific aesthetic elements
- Apply environmental settings for background consistency
- Include weapon/item styling if applicable
- Maintain magical effects consistency
7. **Reference Image Handling**: Determine editing approach:
- If editing a specific image file: use `mcp__nano-banana-mcp__edit_image` with the image path
- If continuing work on the last generated image: use `mcp__nano-banana-mcp__continue_editing`
- Include additional reference images if needed for style transfer or element addition
8. **Image Generation**: Execute the edit using the appropriate MCP tool:
- `mcp__nano-banana-mcp__edit_image` for specific file edits
- `mcp__nano-banana-mcp__continue_editing` for iterative improvements
9. **File Management**: Upon successful generation:
- Save updated image in the same directory structure
- Create versioned filename if preserving original
- Archive the successful edit prompt in corresponding `/prompts/` directory
- Update any cross-references if relationships changed
10. **Documentation**: Create a markdown file in `/prepared_prompts/` directory documenting:
- Original image path and edit description
- Final edit prompt used
- Applied settings and context
- Generated image path
- Edit type and template used
- Validation results
**Edit Types Supported**:
- **Element Addition**: Adding objects, characters, effects to existing image
- **Element Removal**: Removing unwanted elements while maintaining scene integrity
- **Modification**: Changing colors, expressions, poses, clothing, etc.
- **Style Transfer**: Converting image to different artistic style
- **Inpainting**: Replacing specific parts while preserving the rest
- **Composition Changes**: Adjusting framing, perspective, lighting
**Important**:
- The edit prompt must be in English regardless of input language
- Follow exact editing templates from `docs/prompting-guide.md`
- Preserve critical details mentioned in project files
- Maintain consistency with established character/location features
- Use appropriate MCP tool based on editing scenario
- Ensure proper file versioning to preserve original if needed

2
.env Normal file
View File

@ -0,0 +1,2 @@
GEMINI_API_KEY=AIzaSyAWAy39gqmnrYA0kUC3Vh8uadu-WlqJuO4

14
.mcp.json Normal file
View File

@ -0,0 +1,14 @@
{
"mcpServers": {
"nano-banana-mcp": {
"type": "stdio",
"command": "npx",
"args": [
"nano-banana-mcp"
],
"env": {
"GEMINI_API_KEY": "AIzaSyAWAy39gqmnrYA0kUC3Vh8uadu-WlqJuO4"
}
}
}
}

317
CLAUDE.md Normal file
View File

@ -0,0 +1,317 @@
# Fantasy Universe Visual Generation Framework
## Project Overview
This repository contains a comprehensive fantasy universe with parallel worlds, locations, and characters. The system is designed to generate consistent visual representations using Gemini Flash Image (Nano Banana) through Claude Code and the Nano-Banana-MCP integration.
## Project Structure
```
/
├── CLAUDE.md # This file
├── PROJECT_STANDARDS.md # Quality and style requirements
├── cities/
│ └── {city-name}/
│ ├── description.md # City overview and lore
│ ├── images/ # Generated city views
│ ├── prompts/ # Successful prompts archive
│ └── locations/
│ └── {location-name}.md
├── locations/
│ └── {location-name}/
│ ├── description.md # Location details and lore
│ ├── images/ # Generated location images
│ └── prompts/ # Successful prompts archive
├── heroes/
│ └── {hero-name}/
│ ├── description.md # Character details and traits
│ ├── photos/ # Character portraits and scenes
│ └── prompts/ # Character-specific prompts
├── worlds/
│ └── {world-name}/
│ ├── description.md # World rules and aesthetics
│ └── style-guide.md # Visual style requirements
├── items/
│ └── {item-name}/
│ ├── description.md # Item properties and lore
│ ├── images/ # Item visualizations
│ └── prompts/ # Item-specific prompts
├── creatures/
│ └── {creature-name}/
│ ├── description.md # Creature details and abilities
│ ├── images/ # Creature visualizations
│ └── prompts/ # Creature-specific prompts
├── settings/
│ ├── clothing/
│ │ └── {style-name}/
│ │ ├── description.md # Style specifications and usage
│ │ ├── images/ # Reference style images
│ │ └── prompts/ # Style-specific prompts
│ ├── transportation/
│ │ └── {transport-type}/
│ │ ├── description.md # Transportation style details
│ │ ├── images/ # Reference images
│ │ └── prompts/ # Transportation prompts
│ ├── weapons/ # Weapon styles and designs
│ ├── environments/ # Environmental style references
│ ├── architecture-styles/ # Architectural design patterns
│ └── magical-effects/ # Magical visual effect styles
└── scenes/
└── {scene-name}/
├── description.md # Scene context and story
└── images/ # Generated scene images
```
## Entity Relationship System
### Cross-Reference Links
Each entity can reference other entities through standardized linking syntax in their description.md files:
- **Characters**: `[Character:name]` - Links to heroes/{name}/description.md
- **Locations**: `[Location:name]` - Links to locations/{name}/description.md or cities/{city}/locations/{name}.md
- **Worlds**: `[World:name]` - Links to worlds/{name}/description.md
- **Items**: `[Item:name]` - Links to items/{name}/description.md
- **Creatures**: `[Creature:name]` - Links to creatures/{name}/description.md
- **Cities**: `[City:name]` - Links to cities/{name}/description.md
- **Settings**: `[Setting:category/name]` - Links to settings/{category}/{name}/description.md
### Relationship Types
Define relationships between entities using these markers:
- **Ownership**: `[Item:sword-of-power] (owned by this character)`
- **Combat History**: `[Creature:ice-dragon] (defeated by this character)`
- **Location Associations**: `[Location:library] (frequent visitor)`
- **World Origin**: `[World:winter-world] (native to this world)`
- **Character Relationships**: `[Character:camelot] (father of this character)`
- **Item Interactions**: `[Item:mystical-staff] (can be wielded by this character)`
- **Style Preferences**: `[Setting:clothing/ancient-mage-robes] (typical attire for this character)`
## Settings System - Style and Visual References
### Purpose
The `settings/` directory contains reusable visual style references that can be applied across multiple characters, worlds, and scenarios. These are **thematic style guides** rather than specific entities.
### Categories
#### Clothing Settings
- **ancient-mage-robes**: Traditional high-status magical practitioner attire
- **modern-tactical-gear**: Contemporary military/security equipment
- **medieval-noble-attire**: Royal and aristocratic clothing styles
- **casual-modern-wear**: Contemporary everyday clothing
#### Transportation Settings
- **magical-mounts**: Fantasy creature transportation (dragons, unicorns, etc.)
- **modern-vehicles**: Contemporary cars, motorcycles, aircraft
- **medieval-horses**: Traditional horseback transportation
- **futuristic-transport**: Advanced sci-fi transportation methods
#### Weapon Settings
- **medieval-weapons**: Swords, shields, crossbows, traditional arms
- **modern-firearms**: Contemporary weapons and tactical equipment
- **magical-weapons**: Enchanted and mystical weapons
- **futuristic-weapons**: Advanced technology armaments
#### Environment Settings
- **magical-forests**: Enchanted woodland environments
- **urban-landscapes**: Modern city environments
- **ancient-ruins**: Historical and archaeological sites
- **winter-landscapes**: Cold weather and snow environments
#### Architecture Settings
- **medieval-castles**: Traditional fortress and castle designs
- **modern-buildings**: Contemporary architectural styles
- **magical-towers**: Fantasy magical structure designs
- **ancient-temples**: Religious and ceremonial architecture
#### Magical Effects Settings
- **elemental-magic**: Fire, water, earth, air magical visualizations
- **healing-magic**: Positive magical effect visualizations
- **dark-magic**: Shadow and necromantic magical effects
- **protective-magic**: Barrier and shielding magical effects
### Settings Integration in Prompts
#### Automatic Style Application
When generating images, Claude Code should:
1. **Identify applicable settings** based on character, world, and scenario context
2. **Load relevant style descriptions** from settings files
3. **Integrate style elements** into the generated prompt
4. **Maintain consistency** with established character and world aesthetics
#### Example Style Integration
```
Generate [Character:camelot] riding to [Location:guardian-library]
Auto-loaded styles:
- [Setting:clothing/ancient-mage-robes] for Camelot's attire
- [Setting:transportation/magical-mounts] for his transportation
- [World:camelot-world] style guide for overall aesthetic
```
### Style Prompt Template
```
[Base scene description] + [Character with Setting:clothing/style applied] + [Setting:transportation/method if applicable] + [World style context] + [Setting:environment/type for background] + [Technical specifications]
```
## Core Directives for Claude Code
### 1. Context Discovery and Assembly
When receiving image generation requests:
1. **Parse the request** to identify:
- Characters mentioned
- Locations referenced
- Items involved
- Creatures present
- Scene context
- Specific actions or poses
2. **Automatically gather context** by reading relevant files:
- Character descriptions from `/heroes/{character-name}/description.md`
- Location details from `/locations/{location-name}/description.md` or `/cities/{city-name}/locations/{location-name}.md`
- World style guides from `/worlds/{world-name}/description.md` and `/worlds/{world-name}/style-guide.md`
- Item specifications from `/items/{item-name}/description.md`
- Creature details from `/creatures/{creature-name}/description.md`
- **Style settings** from `/settings/{category}/{style-name}/description.md`
- Reference images from appropriate directories
3. **Identify applicable settings** automatically:
- Character clothing based on world, status, and scenario
- Transportation methods appropriate to world and character
- Environmental styles matching the location and world
- Weapon styles suitable for character and scenario
- Magical effects appropriate to character abilities
4. **Follow cross-references** by parsing linked entities:
- When reading a character file, automatically load linked items, locations, and preferred settings
- Resolve creature combat histories for context
- Load world-specific style requirements for characters from different realms
- Apply appropriate setting styles based on character preferences and world context
5. **Synthesize information** into a comprehensive understanding before prompt creation
### 2. Prompt Generation Framework
1. Learn prompting documentation in `docs/prompting-guide.md` with comprehensive guid with best practices of prompting using Gemini 2.5 Flash Image model.
2. Select the best matching case and create a prompt following templates in `docs/prompting-guide.md`, respect best practices described in this document, and adopt them to the actual user request
3. Prepare the professional prompt in English respecting all details and requirements passed by users and this project framework, aligned with documentation, selected template, and best practices
#### Settings Integration Protocol
- **Automatic Style Detection**: Identify appropriate settings based on character, world, and scenario
- **Style Consistency**: Ensure settings align with established character and world aesthetics
- **Hierarchical Application**: World styles > Character preferences > Scenario requirements
- **Style Combination**: Blend multiple settings when appropriate (clothing + transportation + environment)
#### Character Consistency Protocol
- **Always reference unique identifying features** from character descriptions
- **Apply appropriate clothing settings** based on character status, world, and scenario
- **Include owned/wielded items** from character links
- **Maintain physical characteristics** across all generations
- **Use specific descriptors** rather than generic terms
- **Reference previous successful images** when available
- **Consider character relationships** for group scenes
#### Location Consistency Protocol
- **Establish architectural style** from world guidelines and architecture settings
- **Apply appropriate environmental settings** for location type
- **Include signature elements** that make locations recognizable
- **Maintain geographic and environmental logic**
- **Reference existing location images** for consistency
- **Consider location-specific creatures or items**
#### Item Integration Protocol
- **Reference visual descriptions** from item files
- **Apply appropriate weapon/item settings** for visual consistency
- **Maintain consistent appearance** across scenes
- **Consider item-character compatibility** from relationship links
- **Include magical/special effects** if specified using magical-effects settings
#### Creature Integration Protocol
- **Use detailed creature descriptions** for accurate representation
- **Consider creature-character relationships** (combat history, alliances)
- **Include creature abilities** in visual representation using appropriate effect settings
- **Maintain creature consistency** across different scenes
### 3. Settings Usage Examples
#### Clothing Application
```
"Generate Camelot in his study"
→ Auto-applies [Setting:clothing/ancient-mage-robes] based on character status
→ Result: Camelot wearing elaborate blue mage robes with golden runic embroidery
```
#### Transportation Integration
```
"Show Eliot traveling to the Guardian Library"
→ Auto-applies [Setting:transportation/magical-mounts] for fantasy world travel
→ Result: Eliot riding a magical steed appropriate to his mage status
```
#### Environmental Styling
```
"Create a scene in the winter world"
→ Auto-applies [Setting:environments/winter-landscapes] for background
→ Result: Appropriate snow, ice, and cold weather environmental details
```
### 4. Critical Prompting Guidelines
#### ALWAYS DO:
- **Use narrative descriptions** instead of keyword lists
- **Include world-specific style elements** in every prompt
- **Apply appropriate settings automatically** based on context
- **Reference character's unique identifying features** consistently
- **Integrate linked items and relationships** naturally
- **Specify lighting and atmosphere** appropriate to the scene
- **Include technical quality descriptors** for professional results
- **Maintain established visual continuity** across the universe
- **Follow cross-reference links** to gather complete context
- **Apply style settings consistently** across related generations
#### NEVER DO:
- Use disconnected keyword lists
- Ignore established character features
- Generate without consulting existing context files
- Create prompts without world style consistency
- Skip the iterative refinement process
- Forget to specify aspect ratios
- Ignore entity relationships and cross-references
- Apply inappropriate settings that conflict with character or world aesthetics
### 5. File Management Protocol
**Upon Image Approval:**
1. **Save image** to appropriate directory:
- Character portraits → `/heroes/{character-name}/photos/`
- Location shots → `/locations/{location-name}/images/` or `/cities/{city-name}/images/`
- Item visualizations → `/items/{item-name}/images/`
- Creature images → `/creatures/{creature-name}/images/`
- Style references → `/settings/{category}/{style-name}/images/`
- Scene compositions → `/scenes/{scene-name}/images/`
2. **Archive successful prompt** in corresponding `/prompts/` directory with descriptive filename
3. **Update cross-references** if new relationships are established in the scene
4. **Create scene description** if the image represents a specific story moment
5. **Document entity interactions** for future consistency
6. **Archive style applications** in appropriate settings `/prompts/` directories for reuse
### 6. Context Integration Commands
Use these patterns for efficient context gathering:
- `"Generate {character} in {location}"` → Auto-gather character, location, appropriate settings, and linked entity files
- `"Show {character} wielding {item}"` → Gather character and item descriptions, check compatibility, apply weapon settings
- `"Create {character} fighting {creature}"` → Load combat context from character's creature links, apply appropriate combat settings
- `"Show {location} with {creature} present"` → Gather location and creature contexts, apply environmental settings
- `"Generate scene with {character1} and {character2}"` → Load both characters and their relationship context, apply group scene settings
- `"Style {character} in {setting:category/name}"` → Apply specific style override to character
- `"Show {character} in {world} style"` → Apply world-specific styling to character appearance
This framework ensures consistent, high-quality visual generation that maintains narrative coherence, character/location integrity, proper entity relationships, and appropriate style application across the entire fantasy universe project.

133
ENTITIES_CHECKLIST.md Normal file
View File

@ -0,0 +1,133 @@
# Entities Creation Checklist
## Remaining Heroes to Create
### Completed Heroes
- [x] Dan (13 yo boy)
- [x] Nick (14 yo boy)
- [x] Camelot (54 yo, Chief Mage)
- [x] Eliot (18 yo, mage, son of Camelot)
### Heroes to Create
- [ ] Tim (15 yo boy)
- [ ] Edd (18 yo yuan guy, quantum physics student, son of Konstantin)
- [ ] Konstantin (54 yo, Chief physicist of international quantum physics institute)
- [ ] Bart (18 yo, mage, friend of Eliot)
- [ ] Ender (alter ego of Edd, 18 yo, winter mage-assassin)
- [ ] Nataly (44 yo, Vanechka's mom, chemist scientist, works in Gronin lab)
- [ ] Nissa (14 yo girl)
- [ ] Library Guardian (elf-gnome, 1000 years old)
- [ ] Portal Guardian (elf-gnome, 1000 years old)
- [ ] Guardian-Protector (elf-gnome, 1000 years old)
- [ ] Mara (mage from Camelot world, 24 yo girl)
- [ ] George (engineer-builder from modern world, 25 yo)
## Items to Create
- [ ] Dusty Sword (from abandoned building)
- [ ] Dusty Armor (from abandoned building)
- [ ] Archmage Staff
- [ ] Apprentice Mage Staff
- [ ] Mystical Staff (straight, black, polished, no decorations, maximum power)
- [ ] Camelot Staff (high mage staff with green crystal)
- [ ] Owl Figurine (small glass figure of owl, blue colored glass)
- [ ] Gecko Figurine (small glass figure of gecko, blue colored glass)
- [ ] Cat Figurine (small glass figure of jumping cat, blue colored glass)
## Creatures to Create
- [ ] Skeleton (aggressive creature controlled externally)
- [ ] Skeleton Warrior (skeleton with helmet and sword)
- [ ] Zombie (green and stinking aggressive creature)
- [ ] Skeleton Spider (huge 10-meter creature, extremely dangerous)
- [ ] Flying Cat (mad aggressive cat with bat wings, metal claws, burning eyes)
- [ ] Ice Birds (huge pterodactyl-like birds from ice magical substance)
- [ ] Snow Giants (huge creatures made of rough snow lumps)
- [ ] Ice Dragon (dangerous dragon from ice magical substance)
- [ ] Snow Dragon (creature created and controlled by George)
- [ ] Snow Birds (large eagle-like birds made of snow, created by George)
- [ ] Snow Golems (magical snow creatures, Minecraft-like but white and faceless)
## Quick Creation Commands
To create remaining entities quickly, use these patterns:
```bash
# For each hero:
mkdir heroes/{hero-name}
mkdir heroes/{hero-name}/photos
mkdir heroes/{hero-name}/prompts
# For each item:
mkdir items/{item-name}
mkdir items/{item-name}/images
mkdir items/{item-name}/prompts
# For each creature:
mkdir creatures/{creature-name}
mkdir creatures/{creature-name}/images
mkdir creatures/{creature-name}/prompts
```
## Template Description Files
Use these templates for quick creation:
### Hero Template
```markdown
# {Hero Name} - Character Description
## Basic Information
- **Full Name**: {Name}
- **Age**: {Age}
- **Gender**: {Gender}
- **Role**: {Role}
## Cross-References
- **World Origin**: [World:{world-name}]
- **Associates**: [Character:{associate}]
---
*Last Updated: [Date]*
*Consistency Level: STANDARD*
```
### Item Template
```markdown
# {Item Name} - Item Description
## Basic Information
- **Item Name**: {Name}
- **Type**: {Type}
- **Origin**: {Origin}
## Cross-References
- **Found at**: [Location:{location}]
- **Owned by**: [Character:{owner}]
---
*Last Updated: [Date]*
*Consistency Level: STANDARD*
```
### Creature Template
```markdown
# {Creature Name} - Creature Description
## Basic Information
- **Creature Name**: {Name}
- **Type**: {Type}
- **Size**: {Size}
- **Threat Level**: {Level}
## Abilities
- {Ability description}
## Cross-References
- **World Origin**: [World:{world}]
- **Enemies**: [Character:{enemy}]
---
*Last Updated: [Date]*
*Consistency Level: STANDARD*
```

166
PROJECT_STANDARDS.md Normal file
View File

@ -0,0 +1,166 @@
# Project Standards - Fantasy Universe Visual Guidelines
## Universal Quality Requirements
### Technical Standards
- **Resolution**: Minimum 1024x1024 pixels for all generated images
- **Format**: PNG for final images, JPEG acceptable for iterations
- **Aspect Ratios**:
- Character portraits: 3:4 or 1:1
- Location shots: 16:9 or 3:2
- Scene compositions: 16:9 or 2:1 cinematic
- **Quality Level**: Professional, publication-ready imagery
### Visual Consistency Markers
#### Character Requirements
- **Facial Features**: Must remain identical across all generations
- **Body Proportions**: Consistent height, build, and physical characteristics
- **Distinguishing Marks**: Scars, tattoos, birthmarks must appear consistently
- **Hair**: Color, texture, length, and style must match established descriptions
- **Clothing Style**: Character-appropriate attire reflecting their role and world
#### Location Requirements
- **Architectural Style**: Must align with established world-building guidelines
- **Color Palette**: Consistent environmental colors and lighting
- **Scale and Proportions**: Realistic and consistent building/landscape sizes
- **Signature Elements**: Unique identifying features that make locations recognizable
## Art Style Guidelines
### Primary Visual Style
**Fantasy Realism with Cinematic Quality**
- Photorealistic rendering with fantasy elements seamlessly integrated
- Rich, saturated colors with dramatic lighting
- High contrast and depth of field for visual impact
- Professional photography composition principles
### Lighting Philosophy
- **Golden Hour Preference**: Warm, dramatic lighting for most scenes
- **Atmospheric Lighting**: Volumetric effects, god rays, and environmental ambiance
- **Character Lighting**: Three-point lighting setup for portraits
- **Location Lighting**: Natural environmental lighting with enhancement
### Color Palette Framework
#### World-Specific Palettes
**Urban/Civilization Areas:**
- Primary: Warm earth tones (browns, golds, bronze)
- Secondary: Deep blues and purples for magical elements
- Accent: Bright metallics (gold, silver, copper)
**Natural/Wilderness Areas:**
- Primary: Rich greens and earth browns
- Secondary: Sky blues and cloud whites
- Accent: Seasonal colors (autumn reds, spring yellows)
**Magical/Mystical Areas:**
- Primary: Deep purples and midnight blues
- Secondary: Ethereal whites and silvers
- Accent: Glowing energies (electric blue, violet, gold)
## Character Design Standards
### Consistency Requirements
- **Unique Identifier System**: Each character must have 3-5 distinctive features
- **Feature Hierarchy**: Primary (face, hair), Secondary (clothing, accessories), Tertiary (posture, expressions)
- **Evolution Guidelines**: Characters may age or change, but core features remain constant
### Clothing and Accessories
- **Cultural Appropriateness**: Attire must reflect character's origin world/culture
- **Functional Design**: Clothing should serve the character's role and activities
- **Material Consistency**: Fabrics and textures appropriate to world's technology level
- **Symbolic Elements**: Rank insignia, cultural symbols, personal totems
### Expression and Pose Guidelines
- **Personality Reflection**: Facial expressions and body language must match character personality
- **Scene Appropriateness**: Emotions and reactions suitable to narrative context
- **Dynamic Composition**: Avoid static, lifeless poses
- **Interaction Awareness**: Characters should appear naturally integrated into their environment
## Location Design Standards
### Architectural Consistency
- **Cultural Cohesion**: Buildings reflect the civilization that created them
- **Material Logic**: Construction materials available in the world/region
- **Scale Realism**: Proportions appropriate for intended inhabitants
- **Functional Design**: Structures serve clear purposes within the world
### Environmental Integration
- **Geographic Logic**: Landscapes consistent with established world geography
- **Climate Consistency**: Weather and seasonal effects appropriate to region
- **Ecosystem Coherence**: Flora and fauna suitable to the environment
- **Magical Integration**: Supernatural elements naturally woven into the environment
## Scene Composition Standards
### Storytelling Through Imagery
- **Narrative Clarity**: The image should advance or illustrate the story
- **Emotional Resonance**: Visual mood matches narrative tone
- **Character Focus**: Clear protagonist/subject hierarchy
- **Environmental Storytelling**: Background elements support the narrative
### Technical Composition
- **Rule of Thirds**: Strategic placement of key elements
- **Depth Layers**: Foreground, midground, background clearly defined
- **Leading Lines**: Visual elements guide viewer attention
- **Framing**: Natural frames within the scene enhance focus
## Quality Assurance Criteria
### Mandatory Checks
1. **Character Recognition**: Can established characters be immediately identified?
2. **Location Verification**: Does the location match established descriptions?
3. **Style Consistency**: Does the image align with world visual guidelines?
4. **Technical Quality**: Professional-grade execution and clarity?
5. **Narrative Appropriateness**: Does the image serve the story?
### Rejection Criteria
- Character features don't match established descriptions
- Location elements contradict world-building guidelines
- Art style deviates from established visual framework
- Technical quality below professional standards
- Narrative disconnect with established story context
## Iterative Improvement Framework
### Version Control
- **V1**: Initial generation following base prompt
- **V2**: First iteration addressing primary issues
- **V3**: Refinement focusing on consistency and quality
- **Final**: Approved version meeting all standards
### Improvement Priorities
1. **Character Consistency** (highest priority)
2. **Location Accuracy**
3. **Style Alignment**
4. **Technical Quality**
5. **Narrative Enhancement**
### Documentation Requirements
- Archive successful prompts for pattern recognition
- Document failed approaches to avoid repetition
- Maintain consistency logs for character and location evolution
- Track style guide refinements and updates
## Special Considerations
### Cross-Scene Continuity
- Characters must appear consistent across different locations
- Locations must maintain their identity across different scenes
- Time progression should be visually coherent (aging, seasonal changes)
- Magical or supernatural elements should follow established rules
### Cultural Sensitivity
- Fantasy cultures should be internally consistent
- Avoid real-world cultural appropriation in costume and architecture
- Respect the internal logic of created civilizations
- Maintain dignity in character representation
### Technology Integration
- Use available tools (reference images, style guides) effectively
- Leverage prompt engineering best practices
- Maintain backup and version control
- Document successful workflows for replication
This standards document serves as the foundation for all visual generation within the fantasy universe project, ensuring consistent, high-quality imagery that supports and enhances the narrative experience.

162
README.md Normal file
View File

@ -0,0 +1,162 @@
# Magic Building - Fantasy Universe Visual Generation
A comprehensive fantasy universe project designed for consistent visual generation using Gemini Flash Image (Nano Banana) through Claude Code and Nano-Banana-MCP integration.
## Project Status
### ✅ Completed Setup
- **Framework Files**: CLAUDE.md, PROJECT_STANDARDS.md
- **World Structure**: 7 worlds with descriptions and style guides
- **Core Locations**: 6 key locations with descriptions
- **Key Characters**: Main protagonists and antagonists
- **Essential Items**: Magical staffs and artifacts
- **Dangerous Creatures**: Boss-level threats
### 📋 Entities Created
#### Worlds (7/7)
- Modern World
- Winter World
- Giant Snails World
- Kurnog World
- Skeleton World
- Twilight World
- Camelot World
#### Locations (6/6)
- Gronin (modern city)
- Source Castle
- Guardian Library
- Abandoned Building
- Quantum Lab Geneva
- Academy Town Geneva
#### Sample Heroes (4/16)
- Dan (13 yo boy)
- Nick (14 yo boy)
- Camelot (54 yo, Chief Mage)
- Eliot (18 yo, mage, son of Camelot)
- Konstantin (54 yo, quantum physicist)
#### Sample Items (2/9)
- Camelot Staff (high mage staff with green crystal)
- Mystical Staff (ultimate power, minimalist design)
#### Sample Creatures (2/11)
- Skeleton Spider (10m height, extremely dangerous)
- Ice Dragon (ice plasma breath)
## Quick Start Guide
### 1. Installation
Ensure you have:
- Claude Code installed
- Nano-Banana-MCP configured: https://github.com/ConechoAI/Nano-Banana-MCP
- Access to Gemini Flash Image API
### 2. Usage Examples
Generate a character in a location:
```
Generate Archmage Camelot standing in the Central Square of Grenoble
```
Create character with item:
```
Show Eliot wielding the Mystical Staff in the Guardian Library
```
Battle scene:
```
Create Camelot fighting the Skeleton Spider in the Abandoned Building
```
### 3. How It Works
1. **Claude Code parses** your request for entities
2. **Auto-gathers context** from description files and cross-references
3. **Builds comprehensive prompt** following Nano Banana best practices
4. **Generates 3-4 variants** using optimized prompting
5. **Filters and presents** 2 best options
6. **Iterates until approval** with prompt refinement
7. **Archives successful** prompts and images
### 4. Entity Relationship System
Entities are linked using standardized syntax:
- `[Character:name]` - Links to characters
- `[Location:name]` - Links to locations
- `[World:name]` - Links to worlds
- `[Item:name]` - Links to items
- `[Creature:name]` - Links to creatures
Examples:
- `[Character:camelot] (father of this character)`
- `[Item:mystical-staff] (can be wielded by this character)`
- `[Creature:ice-dragon] (defeated by this character)`
## Completion Instructions
### Remaining Work
See `ENTITIES_CHECKLIST.md` for complete list of entities to create.
### Quick Creation Commands
```bash
# Create remaining heroes (12 more)
# Create remaining items (7 more)
# Create remaining creatures (9 more)
```
### File Templates
Use the templates in `ENTITIES_CHECKLIST.md` for consistent entity creation.
## Visual Style Guidelines
### Core Principles
- **Photorealistic fantasy** with cinematic quality
- **Rich, saturated colors** with dramatic lighting
- **Professional composition** following photography principles
- **World-specific consistency** in style and palette
### Image Specifications
- **Resolution**: 1024x1024 minimum
- **Formats**: PNG for finals, JPEG for iterations
- **Aspect Ratios**: 3:4 portraits, 16:9 landscapes, 2:1 cinematic
## Advanced Features
### Cross-Reference Resolution
- Automatic loading of linked entities
- Relationship context in prompts
- Combat history integration
- Item-character compatibility checks
### Iterative Improvement
- Quality filtering based on consistency
- Failure analysis and prompt refinement
- Pattern recognition from successful generations
- Archived prompt reuse
### Batch Processing
- Multiple related generations
- Context continuity across images
- Metadata updates in batches
## Support
### Framework Files
- `CLAUDE.md` - Complete usage framework
- `PROJECT_STANDARDS.md` - Quality and style requirements
- `ENTITIES_CHECKLIST.md` - Remaining work and templates
### Troubleshooting
- Check entity file existence before generation
- Verify cross-references resolve correctly
- Ensure world style guides are properly linked
- Review archived prompts for pattern guidance
---
**Ready to create stunning, consistent fantasy visuals!** 🎨✨
Start with: `"Generate Camelot casting a spell in the Central Square of Grenoble"`

192
SETTINGS_GUIDE.md Normal file
View File

@ -0,0 +1,192 @@
# Settings System - Style Reference Guide
## Overview
The Settings system provides reusable visual style references that can be applied across multiple characters, worlds, and scenarios. These are **thematic style guides** rather than specific entities, designed to ensure consistent visual aesthetics across the universe.
## Available Setting Categories
### 📗 Clothing (settings/clothing/)
Visual style references for character attire across different worlds and scenarios.
#### Created Examples:
- **ancient-mage-robes** - Traditional high-status magical practitioner attire
- Flowing robes, rich fabrics, runic embroidery
- Perfect for [Character:camelot], [Character:eliot], high-ranking mages
- **modern-tactical-gear** - Contemporary military/security equipment
- Functional tactical clothing, protective gear, modern materials
- Suitable for [World:modern-world] action scenarios
#### Suggested Additions:
- **medieval-noble-attire** - Royal and aristocratic clothing
- **casual-modern-wear** - Contemporary everyday clothing
- **winter-survival-gear** - Cold weather protective clothing
- **scholar-robes** - Academic and research attire
### 🚗 Transportation (settings/transportation/)
Vehicle and mount styles for different worlds and scenarios.
#### Created Examples:
- **magical-mounts** - Fantasy creature transportation
- Dragons, unicorns, winged horses, magical steeds
- Perfect for [World:camelot-world] and fantasy travel
#### Suggested Additions:
- **modern-vehicles** - Contemporary cars, motorcycles, aircraft
- **medieval-horses** - Traditional horseback transportation
- **futuristic-transport** - Advanced sci-fi transportation
- **naval-vessels** - Ships and boats for water travel
### ⚔️ Weapons (settings/weapons/)
Weapon styles and designs for different combat scenarios.
#### Suggested Content:
- **medieval-weapons** - Swords, shields, crossbows, traditional arms
- **modern-firearms** - Contemporary weapons and tactical equipment
- **magical-weapons** - Enchanted and mystical weapons
- **futuristic-weapons** - Advanced technology armaments
### 🌲 Environments (settings/environments/)
Background and environmental style references.
#### Suggested Content:
- **magical-forests** - Enchanted woodland environments
- **urban-landscapes** - Modern city environments
- **ancient-ruins** - Historical and archaeological sites
- **winter-landscapes** - Cold weather and snow environments
### 🏰 Architecture Styles (settings/architecture-styles/)
Building and structure design patterns.
#### Suggested Content:
- **medieval-castles** - Traditional fortress and castle designs
- **modern-buildings** - Contemporary architectural styles
- **magical-towers** - Fantasy magical structure designs
- **ancient-temples** - Religious and ceremonial architecture
### ✨ Magical Effects (settings/magical-effects/)
Visual effect styles for magical phenomena.
#### Suggested Content:
- **elemental-magic** - Fire, water, earth, air magical visualizations
- **healing-magic** - Positive magical effect visualizations
- **dark-magic** - Shadow and necromantic magical effects
- **protective-magic** - Barrier and shielding magical effects
## How Settings Work
### Automatic Application
Claude Code automatically applies appropriate settings based on:
- **Character Status**: High-ranking characters get more elaborate styles
- **World Context**: Settings must match the world's technology/magic level
- **Scenario Requirements**: Combat, formal, casual, travel scenarios need different styles
- **Character Preferences**: Established style preferences from character descriptions
### Cross-References Integration
Settings can be explicitly referenced in entity descriptions:
```markdown
## Cross-References
- **Typical Attire**: [Setting:clothing/ancient-mage-robes]
- **Preferred Transportation**: [Setting:transportation/magical-mounts]
- **Combat Style**: [Setting:weapons/magical-weapons]
```
### Style Override Commands
Users can request specific style applications:
- `"Style Camelot in modern tactical gear"` - Apply unusual style for contrast
- `"Show Eliot in ancient mage robes"` - Apply formal attire
- `"Generate Nataly in winter survival gear"` - Apply environmental clothing
## Creating New Settings
### File Structure Template
```
settings/{category}/{style-name}/
├── description.md # Comprehensive style guide
├── images/ # Reference images for the style
└── prompts/ # Successful prompts using this style
```
### Description Template
```markdown
# {Style Name} - {Category} Setting
## Basic Information
- **Setting Name**: {Style Name}
- **Category**: {Category}
- **Style Period**: {Time period/aesthetic}
- **Application**: {When/who uses this style}
## Visual Characteristics
[Detailed visual description]
## Applicable Worlds and Characters
[Cross-references to compatible entities]
## Usage Guidelines
[How and when to apply this style]
## Prompt Integration Notes
[Keywords and phrases for prompt generation]
```
## Style Combination Rules
### Compatible Combinations
- **ancient-mage-robes** + **magical-mounts** = Classic high fantasy aesthetic
- **modern-tactical-gear** + **modern-vehicles** = Contemporary action scenario
- **winter-survival-gear** + **winter-landscapes** = Cold environment survival
### Incompatible Combinations
- **ancient-mage-robes** + **modern-vehicles** = Avoid unless specifically requested
- **modern-tactical-gear** + **magical-mounts** = Requires careful narrative justification
- **medieval-weapons** + **futuristic-environments** = Only for specific crossover scenarios
## Quality Standards
### Visual Consistency
- Settings must align with established world aesthetics
- Character status should be reflected in style complexity
- Environmental appropriateness is essential
### Narrative Appropriateness
- Styles must serve the story and character development
- Anachronistic combinations require narrative justification
- Cultural sensitivity in style design and application
### Technical Standards
- All settings follow PROJECT_STANDARDS.md requirements
- High-quality reference materials and detailed descriptions
- Successful prompt patterns documented for reuse
## Integration with Existing Entities
### Character Applications
- **[Character:camelot]**: ancient-mage-robes, magical-mounts, magical-weapons
- **[Character:nataly]**: modern-casual-wear, modern-vehicles, modern-environments
- **[Character:eliot]**: ancient-mage-robes (simpler), magical-mounts, apprentice-weapons
### World Compatibility
- **[World:camelot-world]**: All magical and medieval settings appropriate
- **[World:modern-world]**: Contemporary settings only
- **[World:winter-world]**: Winter-themed settings, magical ice effects
### Location Enhancement
- **[Location:central-castle]**: medieval-architecture, magical-effects, ancient-weapons
- **[City:gronin]**: modern-architecture, urban-environments, contemporary-styles
## Future Expansion
### Priority Categories
1. **Weapons** - Essential for combat scenarios
2. **Environments** - Critical for location consistency
3. **Architecture Styles** - Important for location and world building
4. **Magical Effects** - Key for fantasy world visualization
### Style Suggestions
- **Steampunk Elements** - For worlds mixing magic and technology
- **Cyberpunk Aesthetics** - For futuristic modern world scenarios
- **Post-Apocalyptic** - For destroyed world environments
- **Underwater Themes** - For aquatic world and creature scenarios
The Settings system ensures that every generated image maintains high visual quality and narrative consistency while providing flexibility for creative storytelling across the universe.

View File

@ -0,0 +1,143 @@
# Grenoble - Medieval Fantasy City
## Basic Information
- **City Name**: Grenoble
- **Type**: Fortified medieval fantasy city
- **World**: [World:camelot-world]
- **Government**: Mage Guild Council
- **Population**: Mixed magical and non-magical citizens
- **Primary Function**: Center of magical learning and knightly orders
## Architectural Signature Elements (NEVER CHANGE)
### Core Structures
- **Central Castle**: Massive stone castle with twin cylindrical towers topped with crenellated battlements
- **Defensive Walls**: Thick stone walls with regular watchtowers on three sides
- **Stone Bridge**: Wide multi-arched bridge crossing the defensive river
- **Main Gates**: Massive fortified entrance flanked by garrison watchtowers
### Distinctive Visual Markers
- **Twin Towers**: Iconic cylindrical towers dominating the city skyline
- **Weathered Sandstone**: Primary building material creating warm, aged appearance
- **Terra Cotta Roofs**: Distinctive red-orange clay tile roofing throughout the city
- **Cobblestone Streets**: Narrow winding medieval streets in organic pattern
- **Timber Framing**: Traditional medieval construction with exposed wooden frameworks
### Material Palette
- **Stone**: Weathered sandstone for walls and foundations
- **Wood**: Dark timber framing and shutters
- **Roofing**: Red-orange terra cotta clay tiles
- **Metalwork**: Iron fixtures and defensive elements
## Districts and Locations
### Central Castle District
- **[Location:central-castle]**: Mage Guild headquarters and [Character:camelot]'s residence
- **Castle Grounds**: Training chambers, laboratories, libraries, council halls
- **Magical Infrastructure**: Enchanted facilities for magical research and education
### Civic Center
- **[Location:central-square]**: Main town square with town hall as focal point
- **Commercial District**: Traditional markets and merchant establishments
- **Administrative Buildings**: Civic governance and guild offices
### Residential Districts
- **Noble Quarter**: Higher-status residences near the castle
- **Artisan District**: Craftsmen and magical item creators
- **Common Quarter**: General population housing
### Defensive Perimeter
- **[Location:main-gates]**: Primary fortified entrance with garrison
- **Watchtowers**: Regular defensive posts along the walls
- **River Boundary**: Natural defense on fourth side
## Transportation Network
### Primary Routes
- **Main Thoroughfare**: Bridge → Main Gates → Central Square → Castle entrance
- **Secondary Streets**: Organic medieval street network branching from main route
- **Waterway Access**: River provides trade and transportation routes
### Bridge System
- **Stone Bridge**: Multi-arched defensive bridge with strategic importance
- **Moat Crossing**: Controlled access point for all land-based entry
## Society and Culture
### Population Composition
- **Magical Practitioners**: Mages, apprentices, magical researchers
- **Knights and Guards**: Military orders and city defense
- **Craftsmen**: Artisans specializing in magical and mundane goods
- **Merchants**: Trade specialists and shop owners
- **Common Citizens**: General population supporting the magical community
### Cultural Focus
- **Magical Education**: Primary center for magical learning and advancement
- **Martial Traditions**: Knightly orders and combat training
- **Craftsmanship**: High-quality magical and mundane item production
- **Community Integration**: Harmonious coexistence of magical and non-magical citizens
## Environmental Characteristics
### Natural Features
- **Defensive River**: Wide flowing river providing protection and water source
- **Elevated Position**: Castle positioned on high ground for defense and visibility
- **Surrounding Landscape**: Medieval countryside with agricultural support
### Climate and Atmosphere
- **Temperate Climate**: Suitable for year-round habitation and agriculture
- **Magical Ambiance**: Subtle magical energy throughout the city
- **Medieval Authenticity**: Genuine medieval atmosphere with fantasy integration
## Visual Generation Guidelines
### Preferred Camera Angles
- **Castle Overview**: Elevated shots showing twin towers and city layout
- **Street Level**: Ground perspective showing medieval architecture and daily life
- **Bridge Approach**: Dramatic view of fortified entrance from bridge
- **Central Square**: Community gathering space with town hall focal point
### Lighting Recommendations
- **Golden Hour**: Warm lighting on sandstone creates beautiful contrast
- **Evening**: Magical illumination from castle and guild facilities
- **Daytime**: Clear lighting showing architectural details and bustling activity
### Seasonal Variations
- **Spring/Summer**: Vibrant colors, active street life, clear skies
- **Autumn**: Warm colors complementing terra cotta roofs
- **Winter**: Light snow on roofs, warm glows from windows
## Cross-References
### Residents
- **[Character:camelot]**: Chief Mage, lives in central castle
- **[Character:eliot]**: Son of Camelot, initiated mage
- **[Character:bart]**: Young mage, friend of Eliot
### Key Locations
- **[Location:central-castle]**: Mage Guild headquarters and Camelot's residence
- **[Location:central-square]**: Main civic and commercial center
- **[Location:main-gates]**: Primary defensive entrance
### Associated Items
- **[Item:camelot-staff]**: Wielded by the city's chief mage
- **[Item:apprentice-staff]**: Used by mage students in the guild
### World Context
- **[World:camelot-world]**: Native realm with high magical civilization
## Reference Image Status
- **City Overview**: [Pending - wide shot showing castle and layout]
- **Castle Detail**: [Pending - close-up of twin towers and architecture]
- **Street Scene**: [Pending - medieval street life and buildings]
- **Bridge Approach**: [Pending - dramatic entrance view]
## Subdirectories
- `images/` - Generated city images
- `prompts/` - Successful prompts archive
- `locations/` - Detailed descriptions of specific locations within the city
---
*Last Updated: [Date]*
*Visual Consistency Level: LOCKED - Core architectural elements cannot be changed*
*Established as home city of Archmage Camelot and center of magical civilization*

Binary file not shown.

After

Width:  |  Height:  |  Size: 215 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 245 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 214 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 163 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 217 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 295 KiB

View File

@ -0,0 +1,66 @@
# Central Castle - Location Description
## Basic Information
- **Location Name**: Central Castle
- **Type**: Mage Guild headquarters and residence
- **City**: [City:grenoble]
- **World**: [World:camelot-world]
- **Function**: Magical education, research, and governance center
## Architectural Signature Elements (NEVER CHANGE)
### Core Structures
- **Twin Cylindrical Towers**: Iconic paired towers with crenellated battlements
- **Weathered Sandstone Construction**: Massive stone blocks creating imposing fortress
- **Main Keep**: Central residential and administrative building
- **Guild Halls**: Specialized chambers for magical council meetings
### Interior Facilities
- **Archmage's Residence**: Private quarters for [Character:camelot]
- **Extensive Libraries**: Vast collections of magical knowledge and research
- **Magical Laboratories**: Equipped facilities for magical experimentation
- **Training Chambers**: Practice spaces for magical and combat instruction
- **Council Halls**: Meeting rooms for guild deliberations and decisions
### Distinctive Features
- **Elevated Position**: Positioned on high ground dominating city skyline
- **Magical Infrastructure**: Enchanted facilities integrated throughout structure
- **Defensive Design**: Military architecture adapted for magical community
- **Tower Visibility**: Twin towers serve as landmarks visible throughout region
## Daily Operations
### Guild Activities
- **Magical Education**: Training of apprentice mages and advanced practitioners
- **Research Projects**: Ongoing magical experimentation and development
- **Council Meetings**: Guild governance and policy decisions
- **Community Services**: Magical assistance to city and surrounding areas
### Residential Function
- **Archmage's Quarters**: Private residence of [Character:camelot]
- **Guest Accommodations**: Facilities for visiting dignitaries and scholars
- **Staff Housing**: Living quarters for guild personnel and servants
## Visual Generation Guidelines
### Preferred Angles
- **Exterior Overview**: Show twin towers and imposing fortress structure
- **Courtyard Views**: Interior spaces showing magical activities
- **Tower Details**: Close-ups of architectural features and magical elements
- **Throne Room/Council**: Interior shots of important ceremonial spaces
### Lighting Characteristics
- **Magical Illumination**: Soft glows from enchanted lighting systems
- **Natural Light**: Large windows providing bright interior illumination
- **Evening Atmosphere**: Warm lights creating welcoming magical ambiance
## Cross-References
- **Primary Resident**: [Character:camelot] (Archmage)
- **Regular Visitors**: [Character:eliot], [Character:bart]
- **Associated Items**: [Item:camelot-staff], [Item:archmage-staff]
- **Parent City**: [City:grenoble]
- **World Context**: [World:camelot-world]
---
*Last Updated: [Date]*
*Consistency Level: LOCKED - Architectural signature elements established*

View File

@ -0,0 +1,71 @@
# Central Square - Location Description
## Basic Information
- **Location Name**: Central Square
- **Type**: Main civic and commercial center
- **City**: [City:grenoble]
- **World**: [World:camelot-world]
- **Function**: Town hall, markets, community gathering space
## Architectural Signature Elements (NEVER CHANGE)
### Core Structures
- **Town Hall**: Central civic building serving as focal point of the square
- **Cobblestone Plaza**: Traditional medieval paving with weathered stone
- **Surrounding Buildings**: Timber-framed structures with terra cotta roofs
- **Market Stalls**: Traditional medieval commercial infrastructure
### Distinctive Features
- **Open Layout**: Spacious plaza allowing for community gatherings
- **Medieval Architecture**: Consistent timber-framed buildings with period details
- **Central Positioning**: Located on main thoroughfare between gates and castle
- **Commercial Integration**: Markets and shops integrated into surrounding structures
## Daily Activities
### Civic Functions
- **Town Governance**: Administrative activities in town hall
- **Public Announcements**: Official proclamations and community notices
- **Legal Proceedings**: Civil matters and dispute resolution
- **Community Meetings**: Gatherings for local issues and celebrations
### Commercial Activities
- **Daily Markets**: Regular trading of goods and provisions
- **Artisan Sales**: Local craftsmen displaying and selling their work
- **Merchant Trading**: Commercial exchanges and business dealings
- **Seasonal Fairs**: Special events and festival markets
### Social Functions
- **Community Gatherings**: Social events and public celebrations
- **Cultural Events**: Performances, storytelling, and entertainment
- **Religious Observances**: Ceremonial activities and festivals
- **Information Exchange**: News sharing and social interaction
## Visual Generation Guidelines
### Preferred Angles
- **Square Overview**: Wide shots showing town hall and surrounding buildings
- **Market Activity**: Street-level views of daily commercial life
- **Architectural Details**: Close-ups of medieval building features
- **Community Events**: Scenes of gatherings and celebrations
### Activity Levels
- **Busy Market Day**: Crowded with merchants, customers, and daily activity
- **Quiet Morning**: Peaceful early hours with minimal activity
- **Festival Time**: Celebration scenes with decorations and festivities
- **Evening Calm**: Sunset lighting with people returning home
### Lighting Recommendations
- **Natural Daylight**: Clear lighting showing architectural details
- **Golden Hour**: Warm lighting on timber and stone creating atmospheric glow
- **Market Ambiance**: Busy daytime lighting with shadows and activity
## Cross-References
- **Parent City**: [City:grenoble]
- **Main Route**: Located on thoroughfare from [Location:main-gates] to [Location:central-castle]
- **World Context**: [World:camelot-world]
- **Nearby Residents**: [Character:camelot], [Character:eliot], [Character:bart]
---
*Last Updated: [Date]*
*Consistency Level: LOCKED - Medieval architecture and layout established*

View File

@ -0,0 +1,87 @@
# Main Gates - Location Description
## Basic Information
- **Location Name**: Main Gates
- **Type**: Fortified city entrance
- **City**: [City:grenoble]
- **World**: [World:camelot-world]
- **Function**: Primary defensive entrance and checkpoint
## Architectural Signature Elements (NEVER CHANGE)
### Core Structures
- **Massive Gate Structure**: Imposing fortified entrance with thick stone construction
- **Flanking Watchtowers**: Twin towers housing city garrison on either side of gates
- **Stone Bridge Approach**: Wide multi-arched bridge crossing defensive moat
- **Portcullis System**: Heavy iron gate providing additional security layer
- **Guard Quarters**: Integrated barracks and defensive facilities
### Defensive Features
- **Thick Stone Walls**: Continuation of city's defensive perimeter
- **Murder Holes**: Defensive openings in gate ceiling for protection
- **Arrow Slits**: Strategic openings for defensive archery
- **Reinforced Doors**: Heavy wooden gates reinforced with iron bands
- **Moat Crossing**: Controlled bridge access with defensive positioning
### Bridge Architecture
- **Multi-Arched Design**: Stone bridge with multiple supporting arches
- **Defensive Width**: Wide enough for trade wagons but controllable
- **Strategic Position**: Only land-based access point to the city
- **River Crossing**: Spans the defensive river boundary
## Daily Operations
### Security Functions
- **Gate Guard Duty**: Continuous security presence and visitor monitoring
- **Customs Inspection**: Examination of goods and travelers entering city
- **Traffic Control**: Managing flow of people, goods, and animals
- **Emergency Response**: First line of defense against external threats
### Commercial Activities
- **Trade Inspection**: Verification of merchant goods and documentation
- **Toll Collection**: Fees for city access and market privileges
- **Traveler Services**: Information and assistance for visitors
- **Accommodation Referrals**: Directing visitors to appropriate lodging
## Guard Operations
### Personnel
- **Gate Captain**: Senior officer commanding gate security
- **Watchmen**: Regular guards maintaining security shifts
- **Customs Officers**: Specialists handling trade and taxation
- **Messenger Service**: Communication with castle and other city areas
### Procedures
- **Visitor Screening**: Evaluation of entering persons and purposes
- **Goods Inspection**: Examination of trade materials and contraband detection
- **Emergency Protocols**: Procedures for threats and city lockdown
- **Record Keeping**: Documentation of significant entries and events
## Visual Generation Guidelines
### Preferred Angles
- **Bridge Approach**: Dramatic view showing full gate structure and defensive position
- **Gate Detail**: Close-up shots of architectural features and defensive elements
- **Guard Activity**: Scenes showing daily security and inspection operations
- **Overhead View**: Strategic perspective showing bridge, moat, and defensive layout
### Activity Scenarios
- **Busy Day**: Multiple travelers, merchants, and guards active
- **Inspection Scene**: Detailed examination of goods or suspicious visitors
- **Evening Watch**: Quiet guard duty with atmospheric lighting
- **Emergency Alert**: Defensive preparations or threat response
### Lighting Recommendations
- **Daytime Security**: Clear lighting showing all defensive features
- **Evening Watch**: Torch and lamplight creating atmospheric security scene
- **Dawn Patrol**: Early morning light with changing of guard
## Cross-References
- **Parent City**: [City:grenoble]
- **Connected Route**: Main thoroughfare leading to [Location:central-square] and [Location:central-castle]
- **World Context**: [World:camelot-world]
- **Defensive Network**: Part of comprehensive city fortification system
---
*Last Updated: [Date]*
*Consistency Level: LOCKED - Defensive architecture and strategic positioning established*

View File

@ -0,0 +1,20 @@
# Grenoble - Capital City of the Mages Guild
## Basic Information
- **Type**: Capital City
- **World**: [World:camelot-world]
- **Time Period**: [Location:kris-era] and beyond
- **Notable Resident**: [Character:kris] (Battle Mage)
## Overview
The major city housing the Capital Mages Guild where [Character:kris] served as a distinguished Battle Mage. As a center of magical learning and guild operations, Grenoble played a crucial role in the defense against supernatural threats during [Location:kris-era].
## Notable Features
- **Capital Mages Guild**: Primary magical institution where [Character:kris] held rank
- **Guild Headquarters**: Central command for magical defense operations
- **Mage Training Facilities**: Where battle mages like [Character:kris] honed their skills
## Historical Significance
During [Location:kris-era], Grenoble served as the launching point for [Character:kris]'s various missions, including his response to the undead invasion at [Location:tri-peskary] and his resistance against [Character:supreme-mage].
*[Placeholder - needs detailed expansion]*

View File

@ -0,0 +1,106 @@
# Gronin - Modern City
## Basic Information
- **City Name**: Gronin
- **Type**: Contemporary urban center
- **World**: [World:modern-world]
- **Population**: Mixed urban population
- **Primary Function**: Modern industrial and research city
## Urban Characteristics
### Architecture and Infrastructure
- **Building Types**: Modern skyscrapers, office buildings, residential complexes
- **Infrastructure**: Advanced transportation, utilities, and communication systems
- **Urban Planning**: Contemporary city layout with zoned districts
- **Technology Level**: 21st century standards with modern amenities
### Distinctive Features
- **Skyline**: Modern cityscape with high-rise buildings
- **Transportation**: Public transit, highways, urban mobility systems
- **Commercial Districts**: Shopping centers, business complexes, financial districts
- **Residential Areas**: Modern neighborhoods and apartment complexes
## Districts and Areas
### Commercial Center
- **Business District**: Corporate offices and financial institutions
- **Shopping Areas**: Retail centers and commercial establishments
- **Service Sector**: Restaurants, entertainment, and urban services
### Industrial Zone
- **Manufacturing**: Modern industrial facilities
- **Research Facilities**: Science and technology research centers
- **Logistics**: Transportation and distribution hubs
### Residential Districts
- **Urban Neighborhoods**: Modern housing developments
- **Apartment Complexes**: High-density residential buildings
- **Suburban Areas**: Lower-density residential zones
## Society and Culture
### Population Composition
- **Professionals**: Scientists, engineers, business professionals
- **Industrial Workers**: Manufacturing and technical personnel
- **Service Workers**: Retail, hospitality, and urban services
- **Researchers**: Academic and corporate research staff
### Economic Focus
- **Industry**: Modern manufacturing and production
- **Research**: Scientific and technological advancement
- **Commerce**: Urban trade and business activities
- **Services**: Modern urban service economy
## Environmental Characteristics
### Urban Environment
- **Climate**: Temperate urban climate
- **Infrastructure**: Modern utilities and city services
- **Transportation**: Advanced urban mobility systems
- **Sustainability**: Contemporary environmental considerations
## Visual Generation Guidelines
### Preferred Angles
- **City Overview**: Wide shots showing modern skyline and urban layout
- **Street Level**: Ground perspective showing modern city life and architecture
- **Business District**: Commercial and financial district scenes
- **Residential Areas**: Modern neighborhood and living spaces
### Lighting Recommendations
- **Natural Daylight**: Clear lighting showing architectural details and urban activity
- **Evening**: City lights and urban illumination
- **Night**: Urban nightscape with building lights and street lighting
### Activity Scenarios
- **Business Hours**: Active commercial and professional activity
- **Rush Hour**: Transportation and commuter scenes
- **Evening Life**: Urban entertainment and social activities
- **Quiet Hours**: Peaceful residential and park areas
## Cross-References
### Residents
- **[Character:nataly]**: Scientist and researcher, works in city laboratory
### World Context
- **[World:modern-world]**: Contemporary Earth-like reality with modern technology
### Related Locations
- **Laboratory Facilities**: Modern research and development centers where [Character:nataly] works
## Reference Image Status
- **City Overview**: [Pending - modern skyline and urban landscape]
- **Business District**: [Pending - commercial and office areas]
- **Residential Areas**: [Pending - modern neighborhoods]
- **Street Scenes**: [Pending - urban life and activity]
## Subdirectories
- `images/` - Generated city images
- `prompts/` - Successful prompts archive
---
*Last Updated: [Date]*
*Visual Consistency Level: STANDARD - Modern urban environment*
*Contemporary city in modern world setting*

View File

@ -0,0 +1,32 @@
# Ice Dragon - Creature Description
## Basic Information
- **Creature Name**: Ice Dragon
- **Type**: Magical ice construct
- **Size**: Large dragon
- **Threat Level**: Dangerous
- **World Origin**: [World:winter-world]
## Physical Description
- **Material**: Ice magical substance
- **Form**: Dragon-like creature
- **Color**: Ice blue/white
## Abilities
- **Ice Plasma Breath**: Shoots ice plasma that can burn through thick stone walls
## Combat Notes
- **Dangerous Opponent**: Requires experienced combatants
- **Destructive Breath**: Can destroy fortifications
## Cross-References
- **World**: [World:winter-world]
- **Related Creatures**: [Creature:snow-dragon], [Creature:ice-birds], [Creature:snow-giants]
## Subdirectories
- `images/` - Creature visualizations
- `prompts/` - Creature-specific prompts
---
*Last Updated: [Date]*
*Consistency Level: STANDARD*

View File

@ -0,0 +1,20 @@
# Skeleton Queen - The Transformed Lady
## Basic Information
- **True Identity**: [Character:lady-tamara]
- **Type**: Undead Noble/Cursed Being
- **World**: [World:camelot-world] during [Location:kris-era]
- **Encountered by**: [Character:kris]
## Overview
The Skeleton Queen was the transformed state of [Character:lady-tamara], who had been exiled from her rightful castle inheritance by [Character:lord-venedikt]. Through unknown dark circumstances, her exile led to her transformation into this undead form.
## Abilities
- Undead command and control
- Royal authority from her previous life
- Connection to dark magic through her transformation
## Story Arc
[Character:kris] traveled to a remote region of the kingdom to confront what he believed to be a typical undead threat. However, upon meeting the Skeleton Queen, he discovered her true identity as the exiled Lady Tamara, revealing a deeper story of injustice and transformation.
*[Placeholder - needs detailed expansion]*

View File

@ -0,0 +1,39 @@
# Skeleton Spider - Creature Description
## Basic Information
- **Creature Name**: Skeleton Spider
- **Type**: Undead construct
- **Size**: Huge (10 meters in height)
- **Threat Level**: Extremely dangerous
- **World Origin**: [World:skeleton-world]
## Physical Description
- **Height**: 10 meters
- **Construction**: Made from numerous small bones
- **Form**: Giant spider-like creature
- **Material**: Assembled skeleton bones
## Abilities
- **Green Poison Jets**: Shoots green poisonous streams
- **Poison Gas**: Releases green poisonous gas
- **Sticky Web**: Spits sticky webbing that restrains heroes
- **Giant Leg Strikes**: Can attack with massive limbs
## Weaknesses
- **Solar Flash Spell**: Can only be defeated by solar flash spell or equivalent power
## Combat Notes
- **Extremely Dangerous**: Requires high-level magic to defeat
- **Multiple Attack Types**: Ranged poison, melee strikes, web restraints
## Cross-References
- **World**: [World:skeleton-world]
- **Related Creatures**: [Creature:skeleton], [Creature:skeleton-warrior]
## Subdirectories
- `images/` - Creature visualizations
- `prompts/` - Creature-specific prompts
---
*Last Updated: [Date]*
*Consistency Level: STANDARD*

256
docs/prompting-guide.md Normal file
View File

@ -0,0 +1,256 @@
# Prompting guide and strategies
Mastering Gemini 2.5 Flash Image Generation starts with one fundamental principle:
Describe the scene, don't just list keywords. The model's core strength is its deep language understanding. A narrative, descriptive paragraph will almost always produce a better, more coherent image than a list of disconnected words.
## Prompts for generating images
The following strategies will help you create effective prompts to generate exactly the images you're looking for.
### 1. Photorealistic scenes
For realistic images, use photography terms. Mention camera angles, lens types, lighting, and fine details to guide the model toward a photorealistic result.
template:
```
A photorealistic [shot type] of [subject], [action or expression], set in
[environment]. The scene is illuminated by [lighting description], creating
a [mood] atmosphere. Captured with a [camera/lens details], emphasizing
[key textures and details]. The image should be in a [aspect ratio] format.
```
example:
```
A photorealistic close-up portrait of an elderly Japanese ceramicist with
deep, sun-etched wrinkles and a warm, knowing smile. He is carefully
inspecting a freshly glazed tea bowl. The setting is his rustic,
sun-drenched workshop. The scene is illuminated by soft, golden hour light
streaming through a window, highlighting the fine texture of the clay.
Captured with an 85mm portrait lens, resulting in a soft, blurred background
(bokeh). The overall mood is serene and masterful. Vertical portrait
orientation.
```
### 2. Stylized illustrations & stickers
To create stickers, icons, or assets, be explicit about the style and request a transparent background.
template:
```
A [style] sticker of a [subject], featuring [key characteristics] and a
[color palette]. The design should have [line style] and [shading style].
The background must be transparent.
```
example:
```
A kawaii-style sticker of a happy red panda wearing a tiny bamboo hat. It's
munching on a green bamboo leaf. The design features bold, clean outlines,
simple cel-shading, and a vibrant color palette. The background must be white.
```
### 3. Accurate text in images
Gemini excels at rendering text. Be clear about the text, the font style (descriptively), and the overall design.
template:
```
Create a [image type] for [brand/concept] with the text "[text to render]"
in a [font style]. The design should be [style description], with a
[color scheme].
```
example:
```
Create a modern, minimalist logo for a coffee shop called 'The Daily Grind'.
The text should be in a clean, bold, sans-serif font. The design should
feature a simple, stylized icon of a a coffee bean seamlessly integrated
with the text. The color scheme is black and white.
```
### 4. Product mockups & commercial photography
Perfect for creating clean, professional product shots for e-commerce, advertising, or branding.
template:
```
A high-resolution, studio-lit product photograph of a [product description]
on a [background surface/description]. The lighting is a [lighting setup,
e.g., three-point softbox setup] to [lighting purpose]. The camera angle is
a [angle type] to showcase [specific feature]. Ultra-realistic, with sharp
focus on [key detail]. [Aspect ratio].
```
example:
```
A high-resolution, studio-lit product photograph of a minimalist ceramic
coffee mug in matte black, presented on a polished concrete surface. The
lighting is a three-point softbox setup designed to create soft, diffused
highlights and eliminate harsh shadows. The camera angle is a slightly
elevated 45-degree shot to showcase its clean lines. Ultra-realistic, with
sharp focus on the steam rising from the coffee. Square image.
```
### 5. Minimalist & negative space design
Excellent for creating backgrounds for websites, presentations, or marketing materials where text will be overlaid.
template:
```
A minimalist composition featuring a single [subject] positioned in the
[bottom-right/top-left/etc.] of the frame. The background is a vast, empty
[color] canvas, creating significant negative space. Soft, subtle lighting.
[Aspect ratio].
```
example:
```
A minimalist composition featuring a single, delicate red maple leaf
positioned in the bottom-right of the frame. The background is a vast, empty
off-white canvas, creating significant negative space for text. Soft,
diffused lighting from the top left. Square image.
```
### 6. Sequential art (Comic panel / Storyboard)`
Builds on character consistency and scene description to create panels for visual storytelling.
template:
```
A single comic book panel in a [art style] style. In the foreground,
[character description and action]. In the background, [setting details].
The panel has a [dialogue/caption box] with the text "[Text]". The lighting
creates a [mood] mood. [Aspect ratio].
```
example:
```
A single comic book panel in a gritty, noir art style with high-contrast
black and white inks. In the foreground, a detective in a trench coat stands
under a flickering streetlamp, rain soaking his shoulders. In the
background, the neon sign of a desolate bar reflects in a puddle. A caption
box at the top reads "The city was a tough place to keep secrets." The
lighting is harsh, creating a dramatic, somber mood. Landscape.
```
## Prompts for editing images
These examples show how to provide images alongside your text prompts for editing, composition, and style transfer.
### 1. Adding and removing elements
Provide an image and describe your change. The model will match the original image's style, lighting, and perspective.
template:
```
Using the provided image of [subject], please [add/remove/modify] [element]
to/from the scene. Ensure the change is [description of how the change should
integrate].
```
example:
```
"Using the provided image of my cat, please add a small, knitted wizard hat
on its head. Make it look like it's sitting comfortably and matches the soft
lighting of the photo."
```
### 2. Inpainting (Semantic masking)
Conversationally define a "mask" to edit a specific part of an image while leaving the rest untouched.
template:
```
Using the provided image, change only the [specific element] to [new
element/description]. Keep everything else in the image exactly the same,
preserving the original style, lighting, and composition.
```
example:
```
"Using the provided image of a living room, change only the blue sofa to be
a vintage, brown leather chesterfield sofa. Keep the rest of the room,
including the pillows on the sofa and the lighting, unchanged."
```
### 3. Style transfer
Provide an image and ask the model to recreate its content in a different artistic style.
template:
```
Transform the provided photograph of [subject] into the artistic style of [artist/art style]. Preserve the original composition but render it with [description of stylistic elements].
```
example:
```
"Transform the provided photograph of a modern city street at night into the artistic style of Vincent van Gogh's 'Starry Night'. Preserve the original composition of buildings and cars, but render all elements with swirling, impasto brushstrokes and a dramatic palette of deep blues and bright yellows."
```
### 4. Advanced composition: Combining multiple images
Provide multiple images as context to create a new, composite scene. This is perfect for product mockups or creative collages.
template:
```
Create a new image by combining the elements from the provided images. Take
the [element from image 1] and place it with/on the [element from image 2].
The final image should be a [description of the final scene].
```
example:
```
"Create a professional e-commerce fashion photo. Take the blue floral dress
from the first image and let the woman from the second image wear it.
Generate a realistic, full-body shot of the woman wearing the dress, with
the lighting and shadows adjusted to match the outdoor environment."
```
### 5. High-fidelity detail preservation
To ensure critical details (like a face or logo) are preserved during an edit, describe them in great detail along with your edit request.
template:
```
Using the provided images, place [element from image 2] onto [element from
image 1]. Ensure that the features of [element from image 1] remain
completely unchanged. The added element should [description of how the
element should integrate].
```
example:
```
"Take the first image of the woman with brown hair, blue eyes, and a neutral
expression. Add the logo from the second image onto her black t-shirt.
Ensure the woman's face and features remain completely unchanged. The logo
should look like it's naturally printed on the fabric, following the folds
of the shirt."
```
## Best Practices
To elevate your results from good to great, incorporate these professional strategies into your workflow.
- Be Hyper-Specific: The more detail you provide, the more control you have. Instead of "fantasy armor," describe it: "ornate elven plate armor, etched with silver leaf patterns, with a high collar and pauldrons shaped like falcon wings."
- Provide Context and Intent: Explain the purpose of the image. The model's understanding of context will influence the final output. For example, "Create a logo for a high-end, minimalist skincare brand" will yield better results than just "Create a logo."
- Iterate and Refine: Don't expect a perfect image on the first try. Use the conversational nature of the model to make small changes. Follow up with prompts like, "That's great, but can you make the lighting a bit warmer?" or "Keep everything the same, but change the character's expression to be more serious."
- Use Step-by-Step Instructions: For complex scenes with many elements, break your prompt into steps. "First, create a background of a serene, misty forest at dawn. Then, in the foreground, add a moss-covered ancient stone altar. Finally, place a single, glowing sword on top of the altar."
- Use "Semantic Negative Prompts": Instead of saying "no cars," describe the desired scene positively: "an empty, deserted street with no signs of traffic."
- Control the Camera: Use photographic and cinematic language to control the composition. Terms like wide-angle shot, macro shot, low-angle perspective.

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.0 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 MiB

View File

@ -0,0 +1,11 @@
# Black Mage - Undead Summoner
## Basic Information
- **Title**: Dark Necromancer
- **World**: [World:camelot-world] during [Location:kris-era]
- **Enemy of**: [Character:kris]
## Overview
A powerful dark mage who initiated an undead invasion from the swamp near [Location:tri-peskary]. Summoned zombies, skeletons, and giant skeleton spiders to terrorize the village. Was ultimately stopped by [Character:kris].
*[Placeholder - needs detailed expansion]*

View File

@ -0,0 +1,51 @@
# Camelot - Character Description
## Basic Information
- **Full Name**: Camelot
- **Age**: 54 years old
- **Gender**: Male
- **Role**: Chief Mage of the Mage Guild in Grenoble
- **World Origin**: [World:camelot-world]
- **Residence**: [City:grenoble], [Location:central-castle]
## Physical Appearance
- **Age Group**: Middle-aged adult (54 years)
- **Gender**: Male
- **Profession**: Archmage and Guild Leader
- **Bearing**: Authoritative presence befitting his high rank
## Magical Abilities
- **Rank**: Archmage - highest level of magical practitioner
- **Specialization**: Guild leadership and advanced magical research
- **Authority**: Commands respect of entire magical community
- **Experience**: Decades of magical practice and leadership
## Residence and Domain
- **Home**: [Location:central-castle] in [City:grenoble]
- **Workspace**: Mage Guild headquarters with libraries, laboratories, and council halls
- **Jurisdiction**: Leadership over magical community in Grenoble and surrounding region
- **Facilities**: Access to extensive magical resources and research materials
## Cross-References
- **Children**: [Character:eliot] (son, initiated mage)
- **Associates**: [Character:bart] (young mage under guild guidance)
- **Home City**: [City:grenoble] - fortified medieval fantasy city
- **Residence**: [Location:central-castle] - Mage Guild headquarters
- **Workplace**: [Location:central-square] - civic center where guild business occurs
- **Signature Item**: [Item:camelot-staff] - high mage staff with green crystal
- **World**: [World:camelot-world] - high fantasy magical realm
- **Guild Facilities**: Access to [Item:archmage-staff] and other guild resources
## Leadership Role
- **Guild Management**: Oversees magical education, research, and community services
- **Community Integration**: Maintains harmony between magical and non-magical citizens
- **Political Influence**: Significant role in city governance and regional affairs
- **Mentorship**: Guides development of younger magical practitioners
## Subdirectories
- `photos/` - Character portraits and scenes
- `prompts/` - Character-specific prompts
---
*Last Updated: [Date]*
*Consistency Level: STANDARD*

Binary file not shown.

After

Width:  |  Height:  |  Size: 215 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 245 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 233 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 214 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 228 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 163 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 217 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 295 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 216 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 269 KiB

23
heroes/dan/description.md Normal file
View File

@ -0,0 +1,23 @@
# Dan - Character Description
## Basic Information
- **Full Name**: Dan
- **Age**: 13 years old
- **Gender**: Boy
- **Role**: Young adventurer
## Physical Appearance
- **Age Group**: Young teenager
- **Gender**: Male
## Cross-References
- **World Origin**: Unknown
- **Associates**: [Character:nick], [Character:tim]
## Subdirectories
- `photos/` - Character portraits and scenes
- `prompts/` - Character-specific prompts
---
*Last Updated: [Date]*
*Consistency Level: STANDARD*

View File

@ -0,0 +1,49 @@
# Eliot - Character Description
## Basic Information
- **Full Name**: Eliot
- **Age**: 18 years old
- **Gender**: Male (yuan guy)
- **Role**: Initiated mage, son of Archmage
- **World Origin**: [World:camelot-world]
- **Residence**: [City:grenoble]
## Physical Appearance
- **Age Group**: Young adult (18 years)
- **Gender**: Male
- **Background**: Yuan heritage
- **Status**: Recently initiated mage
## Magical Development
- **Training Status**: Has passed magical initiation
- **Skill Level**: Junior mage with formal training
- **Potential**: Considerable ability due to heritage and training
- **Education**: Trained in [Location:central-castle] guild facilities
## Family and Social Connections
- **Father**: [Character:camelot] - Archmage and Guild Leader
- **Heritage**: Son of the most powerful mage in the region
- **Social Position**: Privileged status within magical community
- **Expectations**: High expectations due to family legacy
## Cross-References
- **Father**: [Character:camelot] - Chief Mage of Grenoble
- **Friends**: [Character:bart] - fellow young mage
- **Home City**: [City:grenoble] - medieval fantasy city
- **Training Location**: [Location:central-castle] - Mage Guild headquarters
- **World**: [World:camelot-world] - high fantasy magical realm
- **Community**: [Location:central-square] - civic center where he interacts with community
## Development and Future
- **Career Path**: Following in father's footsteps in magical arts
- **Guild Relationship**: Junior member of Mage Guild
- **Community Role**: Next generation of magical leadership
- **Responsibilities**: Learning advanced magical techniques and leadership
## Subdirectories
- `photos/` - Character portraits and scenes
- `prompts/` - Character-specific prompts
---
*Last Updated: [Date]*
*Consistency Level: STANDARD*

Binary file not shown.

After

Width:  |  Height:  |  Size: 580 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.2 MiB

View File

@ -0,0 +1,26 @@
# Konstantin - Character Description
## Basic Information
- **Full Name**: Konstantin
- **Age**: 54 years old
- **Gender**: Male
- **Role**: Chief physicist of international quantum physics institute
- **World Origin**: [World:modern-world]
## Physical Appearance
- **Age Group**: Middle-aged adult
- **Gender**: Male
- **Profession**: Quantum physicist
## Cross-References
- **Children**: [Character:edd] (son)
- **Workplace**: [Location:quantum-lab-geneva]
- **World**: [World:modern-world]
## Subdirectories
- `photos/` - Character portraits and scenes
- `prompts/` - Character-specific prompts
---
*Last Updated: [Date]*
*Consistency Level: STANDARD*

View File

@ -0,0 +1,6 @@
Крис - Боевой маг столичной гильдии магов в Гренобле
28 лет. Быстрый, атлетичный. Он отличный воин и первоклассный боевой маг. Владеет в соверсшенстве многими видами рыцарского оружия, невероятной смекалкой и фантастическими боевыми магическими возможностями. Отдельная особая черта Криса - это его особая "{интуиция боевого мага}", подсказывающая ему о происходящем вокруг, особенно об опастностях и темной магии.
Крис живет в {Гренобле} (в {мире Камелота}). Однако Крис и его история происходили задолго до основной линии повествования. По факту выясняется, что Крис это дедушка Камелота. Поэтому хоть это и тот же самый мир, мы будем поразумевать это как {времена Криса}
Крис остановил вторжение {черного мага}, когда из болота за деревней {три пескаря} с одноименной таверной начали выходить зомби, скелеты и огромные скелеты-пауки. Жители деревни не моги сами оказать достойное сопротивление вторжению или позвать на помощь тк им никто не верил. Но Крис оказался рядом и спас свой мир от вторжения.
Кроме того, Крис, его друзья и другие примкнувшие к нему маги, оказали сопротивление и непокорность {Верховному Магу} который собирался устроить армагеддон и стереть с лица земли всю деревню и болото из которого выходила нечесть. Чтобы остановить начавшийся армагеддон, созданный главным магом, Крис с друзьями замедлил время и создал кокон вокруг армагеддона, аккуратно опустил его на повехность озера, и спрятал создав сверху поле с травой. Однако это хоть и замедлило процесс но не остановило проблему, решать которую придется следующим поколениям
В следующей части Крис отравляется сражаться с {Королевой Скелетов} в одаленном районе своего королевства. Он знакомится с королевой, которой на самом деле является {Леди Тамара} - наследница замка, которую выгнал и пустил по миру {Лорд Венедикт}, являющийсся лучшим другом и советником {Верховного Мага}.

View File

@ -0,0 +1,57 @@
# Kris - Battle Mage of the Capital Guild
## Basic Information
- **Age**: 28 years old
- **Title**: Battle Mage of the Capital Mages Guild in [City:grenoble]
- **World**: [World:camelot-world] (during [Location:kris-era])
- **Relationship**: Grandfather of [Character:camelot]
## Physical Description
Kris is a quick and athletic warrior-mage with an imposing presence. He has dark hair and a well-groomed beard, with piercing eyes that reflect both wisdom and battle-hardened experience. His physique shows the perfect balance of a trained warrior and a scholarly mage.
## Uniform and Attire
Kris wears the distinguished uniform of the Capital Mages Guild, reflecting his high status and combat role:
- **Primary Garment**: A flowing dark navy blue cape with ornate silver trim and decorative patterns along the edges
- **Chest Armor**: Black studded leather chest piece with metallic reinforcements, providing protection while maintaining mobility for spellcasting
- **Under-Layer**: Dark practical tunic suitable for both combat and magical work
- **Belt and Accessories**: Wide leather belt with pouches for spell components and magical implements
- **Overall Style**: [Setting:clothing/battle-mage-uniform] - a perfect blend of martial protection and mage regalia, designed for a high-ranking guild battle mage
The uniform demonstrates his dual nature as both a formidable warrior and a powerful spellcaster, with the rich materials and craftsmanship befitting his status in the guild hierarchy.
## Abilities and Skills
- **Combat Mastery**: Expert in various types of knightly weapons
- **Magical Prowess**: First-class battle mage with fantastic combat magical abilities
- **Battle Intuition**: Possesses a special "battle mage intuition" that alerts him to surrounding dangers and dark magic
- **Quick Thinking**: Incredible wit and strategic thinking in combat situations
## Weapons and Equipment
- [Item:battle-mage-staff] (primary magical focus)
- [Item:guild-ceremonial-blade] (backup weapon)
- Various knightly weapons mastered through training
## Major Accomplishments
### The Undead Invasion
Kris stopped an invasion by [Character:black-mage] when zombies, skeletons, and giant skeleton spiders began emerging from the swamp near the village of [Location:tri-peskary] (named after its tavern). The villagers couldn't mount proper resistance or call for help as no one believed them, but Kris happened to be nearby and saved his world from the invasion.
### Resistance Against the Supreme Mage
Kris, along with his friends and other mages who joined him, offered resistance and defiance against [Character:supreme-mage] who planned to cause an armageddon and wipe the entire village and swamp from the face of the earth. To stop the armageddon created by the Supreme Mage, Kris and his friends slowed time, created a cocoon around the armageddon, carefully lowered it to the lake surface, and hid it by creating a grassy field above. However, this only slowed the process but didn't stop the problem, which future generations would have to solve.
### The Skeleton Queen Campaign
In his next adventure, Kris traveled to fight [Creature:skeleton-queen] in a remote region of his kingdom. He discovered that the Skeleton Queen was actually [Character:lady-tamara] - heir to a castle who was exiled and cast out by [Character:lord-venedikt], who was the best friend and advisor to [Character:supreme-mage].
## Relationships
- **Grandson**: [Character:camelot] (main timeline hero)
- **Allies**: Fellow guild mages and resistance fighters
- **Enemies**: [Character:black-mage], [Character:supreme-mage], [Character:lord-venedikt]
- **Redeemed Enemy**: [Character:lady-tamara] (formerly [Creature:skeleton-queen])
## Location Associations
- **Home Base**: [City:grenoble] in [World:camelot-world]
- **Mission Areas**: [Location:tri-peskary], remote kingdom regions
- **Time Period**: [Location:kris-era] - events occurring long before the main storyline
## Legacy
Kris's actions during his time set the foundation for the world that his grandson Camelot would later inherit. His containment of the Supreme Mage's armageddon created a problem that would echo through generations, while his heroic deeds established him as a legendary figure in the guild's history.

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.0 MiB

View File

@ -0,0 +1,12 @@
# Lady Tamara - The Transformed Heir
## Basic Information
- **True Identity**: Castle heir, formerly known as [Creature:skeleton-queen]
- **World**: [World:camelot-world] during [Location:kris-era]
- **Exiled by**: [Character:lord-venedikt]
- **Encountered by**: [Character:kris]
## Overview
Originally the rightful heir to a castle, Lady Tamara was exiled and cast out by [Character:lord-venedikt]. Through dark circumstances, she became the [Creature:skeleton-queen] that [Character:kris] was sent to fight. Upon meeting her, Kris discovered her true identity and tragic story.
*[Placeholder - needs detailed expansion]*

View File

@ -0,0 +1,12 @@
# Lord Venedikt - The Advisor
## Basic Information
- **Title**: Lord and Advisor
- **World**: [World:camelot-world] during [Location:kris-era]
- **Relationship**: Best friend and advisor to [Character:supreme-mage]
- **Actions**: Exiled [Character:lady-tamara] from her rightful castle
## Overview
A powerful lord who served as the best friend and trusted advisor to the [Character:supreme-mage]. Responsible for exiling [Character:lady-tamara] from her castle inheritance, setting in motion the events that led to her transformation into the [Creature:skeleton-queen].
*[Placeholder - needs detailed expansion]*

View File

@ -0,0 +1,47 @@
# Nataly - Character Description
## Basic Information
- **Full Name**: Nataly
- **Age**: 44 years old
- **Gender**: Female
- **Role**: Scientist chemist, Vanechka's mother
- **World Origin**: [World:modern-world]
- **Residence**: [City:gronin]
## Physical Appearance
- **Age Group**: Middle-aged adult (44 years)
- **Gender**: Female
- **Profession**: Research scientist and chemist
- **Background**: Modern professional woman
## Professional Life
- **Occupation**: Scientist chemist
- **Workplace**: Laboratory in [City:gronin]
- **Specialization**: Chemical research and analysis
- **Experience**: Established career in scientific research
## Family and Personal Life
- **Children**: Vanechka (mother of)
- **Family Role**: Primary caregiver and working mother
- **Work-Life Balance**: Balancing scientific career with parenting responsibilities
- **Living Situation**: Urban life in modern city environment
## Cross-References
- **Home City**: [City:gronin] - modern contemporary city
- **Workplace**: Laboratory facilities in [City:gronin]
- **World**: [World:modern-world] - contemporary Earth-like reality
- **Children**: Vanechka (son, referenced in description)
## Professional Environment
- **Laboratory Work**: Modern research facility environment
- **Scientific Community**: Part of contemporary research establishment
- **Technology Access**: Modern scientific equipment and methodology
- **Career Development**: Established professional in chemical sciences
## Subdirectories
- `photos/` - Character portraits and scenes
- `prompts/` - Character-specific prompts
---
*Last Updated: [Date]*
*Consistency Level: STANDARD*

View File

@ -0,0 +1,18 @@
# Nick - Character Description
## Basic Information
- **Full Name**: Nick
- **Age**: 14 years old
- **Gender**: Boy
- **Role**: Young adventurer
## Physical Appearance
- **Age Group**: Young teenager
- **Gender**: Male
## Cross-References
- **Associates**: [Character:dan], [Character:tim]
---
*Last Updated: [Date]*
*Consistency Level: STANDARD*

View File

@ -0,0 +1,12 @@
# Supreme Mage - The Armageddon Initiator
## Basic Information
- **Title**: Supreme Mage of the Realm
- **World**: [World:camelot-world] during [Location:kris-era]
- **Ally**: [Character:lord-venedikt] (best friend and advisor)
- **Enemy of**: [Character:kris]
## Overview
The highest-ranking mage who planned to cause an armageddon to destroy the village of [Location:tri-peskary] and its surrounding swamp to stop the undead emergence. His extreme solution was opposed by [Character:kris] and other mages. Kris contained the armageddon but only delayed it, leaving the problem for future generations.
*[Placeholder - needs detailed expansion]*

View File

@ -0,0 +1,21 @@
# Battle Mage Staff - Kris's Primary Focus
## Basic Information
- **Type**: Magical Staff/Combat Focus
- **Owner**: [Character:kris]
- **World**: [World:camelot-world] during [Location:kris-era]
- **Style**: [Setting:weapons/magical-weapons]
## Overview
The primary magical implement wielded by [Character:kris] during his service as a Battle Mage of the Capital Guild. This staff serves both as a focus for his combat magic and as a symbol of his rank within the guild hierarchy.
## Properties
- **Magical Focus**: Channels and amplifies battle magic
- **Combat Utility**: Can be used in physical combat when needed
- **Guild Authority**: Represents official rank and standing
- **Battle Intuition Enhancement**: May augment Kris's special battle mage intuition
## Usage
Essential for Kris's magical abilities, particularly during major confrontations such as the undead invasion at [Location:tri-peskary] and his resistance against [Character:supreme-mage]'s armageddon.
*[Placeholder - needs detailed expansion]*

View File

@ -0,0 +1,24 @@
# Camelot Staff - Item Description
## Basic Information
- **Item Name**: Camelot Staff
- **Type**: High mage staff with green crystal
- **Origin**: [World:camelot-world]
- **Material**: Magical wood with green crystal
## Properties
- **Power Level**: High mage tier
- **Crystal Color**: Green
- **Magical Properties**: Enhanced spellcasting
## Cross-References
- **Owner**: [Character:camelot]
- **World**: [World:camelot-world]
## Subdirectories
- `images/` - Item visualizations
- `prompts/` - Item-specific prompts
---
*Last Updated: [Date]*
*Consistency Level: STANDARD*

View File

@ -0,0 +1,21 @@
# Guild Ceremonial Blade - Backup Weapon
## Basic Information
- **Type**: Ceremonial Sword/Backup Weapon
- **Owner**: [Character:kris]
- **World**: [World:camelot-world] during [Location:kris-era]
- **Style**: [Setting:weapons/medieval-weapons]
## Overview
A ceremonial blade carried by [Character:kris] as both a symbol of his guild rank and a practical backup weapon. Represents the dual nature of battle mages who must be skilled in both magical and physical combat.
## Properties
- **Guild Symbolism**: Denotes rank within the Capital Mages Guild
- **Combat Ready**: Functional weapon despite ceremonial nature
- **Quality Craftsmanship**: Befitting a high-ranking guild member
- **Knightly Tradition**: Reflects Kris's mastery of knightly weapons
## Usage
Serves as Kris's secondary weapon when his [Item:battle-mage-staff] is not suitable for close combat situations, demonstrating his comprehensive martial training.
*[Placeholder - needs detailed expansion]*

View File

@ -0,0 +1,25 @@
# Mystical Staff - Item Description
## Basic Information
- **Item Name**: Mystical Staff
- **Type**: Ultimate magical staff
- **Appearance**: Straight, black, polished, no decorations or ornaments
- **Material**: Unknown mystical material
## Properties
- **Power Level**: Maximum power
- **Design**: Minimalist, no decorative elements
- **Color**: Pure black, polished finish
- **Shape**: Perfectly straight
## Special Features
- **Power**: Possesses maximum magical strength
- **Simplicity**: Power through minimalism, not ornamentation
## Subdirectories
- `images/` - Item visualizations
- `prompts/` - Item-specific prompts
---
*Last Updated: [Date]*
*Consistency Level: STANDARD*

View File

@ -0,0 +1,23 @@
# Abandoned Building - Location Description
## Basic Information
- **Location Name**: Abandoned Building
- **Type**: Ruined structure
- **World**: Fantasy realm
- **Setting**: Old, forgotten building
## Visual Style
- **Architecture**: Decaying, ruined building
- **Atmosphere**: Mysterious, dusty, forgotten
- **Condition**: Abandoned and deteriorating
## Cross-References
- **Items Found**: [Item:dusty-sword], [Item:dusty-armor]
## Subdirectories
- `images/` - Generated location images
- `prompts/` - Successful prompts archive
---
*Last Updated: [Date]*
*Consistency Level: STANDARD*

Binary file not shown.

After

Width:  |  Height:  |  Size: 350 KiB

View File

@ -0,0 +1,23 @@
# Academy Town Geneva - Location Description
## Basic Information
- **Location Name**: Academy Town Geneva
- **Type**: Academic district
- **World**: [World:modern-world]
- **Setting**: University and research area in Geneva
## Visual Style
- **Architecture**: Academic buildings and campus
- **Atmosphere**: Educational and scholarly environment
- **Features**: University facilities and student areas
## Cross-References
- **Students**: [Character:edd]
## Subdirectories
- `images/` - Generated location images
- `prompts/` - Successful prompts archive
---
*Last Updated: [Date]*
*Consistency Level: STANDARD*

View File

@ -0,0 +1,23 @@
# Guardian Library - Location Description
## Basic Information
- **Location Name**: Guardian Library
- **Type**: Magical library
- **World**: Fantasy realm
- **Setting**: Ancient repository of knowledge
## Visual Style
- **Architecture**: Mystical library with towering bookshelves
- **Atmosphere**: Ancient wisdom and magical knowledge
- **Guardians**: Protected by magical guardians
## Cross-References
- **Guardian**: [Character:library-guardian]
## Subdirectories
- `images/` - Generated location images
- `prompts/` - Successful prompts archive
---
*Last Updated: [Date]*
*Consistency Level: STANDARD*

View File

@ -0,0 +1,20 @@
# Kris Era - The Age of the Battle Mage
## Basic Information
- **Type**: Historical Time Period
- **World**: [World:camelot-world]
- **Main Hero**: [Character:kris]
- **Relationship to Main Timeline**: Occurs long before [Character:camelot]'s story
## Overview
A significant historical period in [World:camelot-world] when [Character:kris], grandfather of [Character:camelot], served as a Battle Mage of the Capital Guild in [City:grenoble]. This era was marked by supernatural threats, political intrigue, and magical conflicts that would shape the world for generations to come.
## Major Events
- **The Undead Invasion**: [Character:black-mage]'s assault on [Location:tri-peskary]
- **The Armageddon Crisis**: [Character:supreme-mage]'s extreme solution and [Character:kris]'s containment
- **The Skeleton Queen Campaign**: Discovery of [Character:lady-tamara]'s true identity
## Legacy
The actions and decisions made during this era, particularly Kris's containment of the Supreme Mage's armageddon, created ongoing problems that future generations, including [Character:camelot], would need to address.
*[Placeholder - needs detailed expansion]*

View File

@ -0,0 +1,24 @@
# Quantum Laboratory Geneva - Location Description
## Basic Information
- **Location Name**: Quantum Laboratory Geneva
- **Type**: Modern scientific laboratory
- **World**: [World:modern-world]
- **Setting**: Advanced physics research facility in Geneva
## Visual Style
- **Architecture**: Modern laboratory building
- **Equipment**: Advanced quantum physics equipment
- **Atmosphere**: High-tech scientific environment
## Cross-References
- **Director**: [Character:konstantin]
- **Students**: [Character:edd]
## Subdirectories
- `images/` - Generated location images
- `prompts/` - Successful prompts archive
---
*Last Updated: [Date]*
*Consistency Level: STANDARD*

View File

@ -0,0 +1,20 @@
# Source Castle - Location Description
## Basic Information
- **Location Name**: Source Castle
- **Type**: Magical castle
- **World**: Fantasy realm
- **Setting**: Ancient magical fortress
## Visual Style
- **Architecture**: Medieval fantasy castle
- **Atmosphere**: Mystical and ancient
- **Special Features**: Magical source or fountain
## Subdirectories
- `images/` - Generated location images
- `prompts/` - Successful prompts archive
---
*Last Updated: [Date]*
*Consistency Level: STANDARD*

View File

@ -0,0 +1,16 @@
# Tri Peskary - The Village by the Cursed Swamp
## Basic Information
- **Type**: Village
- **World**: [World:camelot-world] during [Location:kris-era]
- **Notable Feature**: Tavern with the same name as the village
- **Threat**: Undead emergence from nearby swamp
## Overview
A small village known for its tavern called "Tri Peskary" (Three Minnows). The village became the center of an undead invasion when [Character:black-mage] caused zombies, skeletons, and giant skeleton spiders to emerge from the nearby swamp. The villagers were unable to defend themselves or call for help as no one believed their reports of the supernatural threat. The village was saved by [Character:kris] who happened to be in the area.
## Locations
- **Tri Peskary Tavern**: The village's main gathering place and namesake
- **The Cursed Swamp**: Source of the undead invasion, located near the village
*[Placeholder - needs detailed expansion]*

21
node_modules/.bin/tsc generated vendored Executable file
View File

@ -0,0 +1,21 @@
#!/bin/sh
basedir=$(dirname "$(echo "$0" | sed -e 's,\\,/,g')")
case `uname` in
*CYGWIN*|*MINGW*|*MSYS*)
if command -v cygpath > /dev/null 2>&1; then
basedir=`cygpath -w "$basedir"`
fi
;;
esac
if [ -z "$NODE_PATH" ]; then
export NODE_PATH="/projects/my-projects/Magic-Building/node_modules/.pnpm/typescript@5.9.2/node_modules/typescript/bin/node_modules:/projects/my-projects/Magic-Building/node_modules/.pnpm/typescript@5.9.2/node_modules/typescript/node_modules:/projects/my-projects/Magic-Building/node_modules/.pnpm/typescript@5.9.2/node_modules:/projects/my-projects/Magic-Building/node_modules/.pnpm/node_modules"
else
export NODE_PATH="/projects/my-projects/Magic-Building/node_modules/.pnpm/typescript@5.9.2/node_modules/typescript/bin/node_modules:/projects/my-projects/Magic-Building/node_modules/.pnpm/typescript@5.9.2/node_modules/typescript/node_modules:/projects/my-projects/Magic-Building/node_modules/.pnpm/typescript@5.9.2/node_modules:/projects/my-projects/Magic-Building/node_modules/.pnpm/node_modules:$NODE_PATH"
fi
if [ -x "$basedir/node" ]; then
exec "$basedir/node" "$basedir/../.pnpm/typescript@5.9.2/node_modules/typescript/bin/tsc" "$@"
else
exec node "$basedir/../.pnpm/typescript@5.9.2/node_modules/typescript/bin/tsc" "$@"
fi

21
node_modules/.bin/tsserver generated vendored Executable file
View File

@ -0,0 +1,21 @@
#!/bin/sh
basedir=$(dirname "$(echo "$0" | sed -e 's,\\,/,g')")
case `uname` in
*CYGWIN*|*MINGW*|*MSYS*)
if command -v cygpath > /dev/null 2>&1; then
basedir=`cygpath -w "$basedir"`
fi
;;
esac
if [ -z "$NODE_PATH" ]; then
export NODE_PATH="/projects/my-projects/Magic-Building/node_modules/.pnpm/typescript@5.9.2/node_modules/typescript/bin/node_modules:/projects/my-projects/Magic-Building/node_modules/.pnpm/typescript@5.9.2/node_modules/typescript/node_modules:/projects/my-projects/Magic-Building/node_modules/.pnpm/typescript@5.9.2/node_modules:/projects/my-projects/Magic-Building/node_modules/.pnpm/node_modules"
else
export NODE_PATH="/projects/my-projects/Magic-Building/node_modules/.pnpm/typescript@5.9.2/node_modules/typescript/bin/node_modules:/projects/my-projects/Magic-Building/node_modules/.pnpm/typescript@5.9.2/node_modules/typescript/node_modules:/projects/my-projects/Magic-Building/node_modules/.pnpm/typescript@5.9.2/node_modules:/projects/my-projects/Magic-Building/node_modules/.pnpm/node_modules:$NODE_PATH"
fi
if [ -x "$basedir/node" ]; then
exec "$basedir/node" "$basedir/../.pnpm/typescript@5.9.2/node_modules/typescript/bin/tsserver" "$@"
else
exec node "$basedir/../.pnpm/typescript@5.9.2/node_modules/typescript/bin/tsserver" "$@"
fi

21
node_modules/.bin/tsx generated vendored Executable file
View File

@ -0,0 +1,21 @@
#!/bin/sh
basedir=$(dirname "$(echo "$0" | sed -e 's,\\,/,g')")
case `uname` in
*CYGWIN*|*MINGW*|*MSYS*)
if command -v cygpath > /dev/null 2>&1; then
basedir=`cygpath -w "$basedir"`
fi
;;
esac
if [ -z "$NODE_PATH" ]; then
export NODE_PATH="/projects/my-projects/Magic-Building/node_modules/.pnpm/tsx@4.20.5/node_modules/tsx/dist/node_modules:/projects/my-projects/Magic-Building/node_modules/.pnpm/tsx@4.20.5/node_modules/tsx/node_modules:/projects/my-projects/Magic-Building/node_modules/.pnpm/tsx@4.20.5/node_modules:/projects/my-projects/Magic-Building/node_modules/.pnpm/node_modules"
else
export NODE_PATH="/projects/my-projects/Magic-Building/node_modules/.pnpm/tsx@4.20.5/node_modules/tsx/dist/node_modules:/projects/my-projects/Magic-Building/node_modules/.pnpm/tsx@4.20.5/node_modules/tsx/node_modules:/projects/my-projects/Magic-Building/node_modules/.pnpm/tsx@4.20.5/node_modules:/projects/my-projects/Magic-Building/node_modules/.pnpm/node_modules:$NODE_PATH"
fi
if [ -x "$basedir/node" ]; then
exec "$basedir/node" "$basedir/../.pnpm/tsx@4.20.5/node_modules/tsx/dist/cli.mjs" "$@"
else
exec node "$basedir/../.pnpm/tsx@4.20.5/node_modules/tsx/dist/cli.mjs" "$@"
fi

159
node_modules/.modules.yaml generated vendored Normal file
View File

@ -0,0 +1,159 @@
hoistPattern:
- '*'
hoistedDependencies:
'@esbuild/aix-ppc64@0.25.9':
'@esbuild/aix-ppc64': private
'@esbuild/android-arm64@0.25.9':
'@esbuild/android-arm64': private
'@esbuild/android-arm@0.25.9':
'@esbuild/android-arm': private
'@esbuild/android-x64@0.25.9':
'@esbuild/android-x64': private
'@esbuild/darwin-arm64@0.25.9':
'@esbuild/darwin-arm64': private
'@esbuild/darwin-x64@0.25.9':
'@esbuild/darwin-x64': private
'@esbuild/freebsd-arm64@0.25.9':
'@esbuild/freebsd-arm64': private
'@esbuild/freebsd-x64@0.25.9':
'@esbuild/freebsd-x64': private
'@esbuild/linux-arm64@0.25.9':
'@esbuild/linux-arm64': private
'@esbuild/linux-arm@0.25.9':
'@esbuild/linux-arm': private
'@esbuild/linux-ia32@0.25.9':
'@esbuild/linux-ia32': private
'@esbuild/linux-loong64@0.25.9':
'@esbuild/linux-loong64': private
'@esbuild/linux-mips64el@0.25.9':
'@esbuild/linux-mips64el': private
'@esbuild/linux-ppc64@0.25.9':
'@esbuild/linux-ppc64': private
'@esbuild/linux-riscv64@0.25.9':
'@esbuild/linux-riscv64': private
'@esbuild/linux-s390x@0.25.9':
'@esbuild/linux-s390x': private
'@esbuild/linux-x64@0.25.9':
'@esbuild/linux-x64': private
'@esbuild/netbsd-arm64@0.25.9':
'@esbuild/netbsd-arm64': private
'@esbuild/netbsd-x64@0.25.9':
'@esbuild/netbsd-x64': private
'@esbuild/openbsd-arm64@0.25.9':
'@esbuild/openbsd-arm64': private
'@esbuild/openbsd-x64@0.25.9':
'@esbuild/openbsd-x64': private
'@esbuild/openharmony-arm64@0.25.9':
'@esbuild/openharmony-arm64': private
'@esbuild/sunos-x64@0.25.9':
'@esbuild/sunos-x64': private
'@esbuild/win32-arm64@0.25.9':
'@esbuild/win32-arm64': private
'@esbuild/win32-ia32@0.25.9':
'@esbuild/win32-ia32': private
'@esbuild/win32-x64@0.25.9':
'@esbuild/win32-x64': private
agent-base@7.1.4:
agent-base: private
base64-js@1.5.1:
base64-js: private
bignumber.js@9.3.1:
bignumber.js: private
buffer-equal-constant-time@1.0.1:
buffer-equal-constant-time: private
debug@4.4.1:
debug: private
ecdsa-sig-formatter@1.0.11:
ecdsa-sig-formatter: private
esbuild@0.25.9:
esbuild: private
extend@3.0.2:
extend: private
fsevents@2.3.3:
fsevents: private
gaxios@6.7.1:
gaxios: private
gcp-metadata@6.1.1:
gcp-metadata: private
get-tsconfig@4.10.1:
get-tsconfig: private
google-auth-library@9.15.1:
google-auth-library: private
google-logging-utils@0.0.2:
google-logging-utils: private
gtoken@7.1.0:
gtoken: private
https-proxy-agent@7.0.6:
https-proxy-agent: private
is-stream@2.0.1:
is-stream: private
json-bigint@1.0.0:
json-bigint: private
jwa@2.0.1:
jwa: private
jws@4.0.0:
jws: private
ms@2.1.3:
ms: private
node-fetch@2.7.0:
node-fetch: private
resolve-pkg-maps@1.0.0:
resolve-pkg-maps: private
safe-buffer@5.2.1:
safe-buffer: private
tr46@0.0.3:
tr46: private
undici-types@7.10.0:
undici-types: private
uuid@9.0.1:
uuid: private
webidl-conversions@3.0.1:
webidl-conversions: private
whatwg-url@5.0.0:
whatwg-url: private
ws@8.18.3:
ws: private
included:
dependencies: true
devDependencies: true
optionalDependencies: true
injectedDeps: {}
layoutVersion: 5
nodeLinker: isolated
packageManager: pnpm@10.11.0
pendingBuilds: []
prunedAt: Mon, 08 Sep 2025 15:39:10 GMT
publicHoistPattern: []
registries:
'@jsr': https://npm.jsr.io/
default: https://registry.npmjs.org/
skipped:
- '@esbuild/aix-ppc64@0.25.9'
- '@esbuild/android-arm64@0.25.9'
- '@esbuild/android-arm@0.25.9'
- '@esbuild/android-x64@0.25.9'
- '@esbuild/darwin-arm64@0.25.9'
- '@esbuild/darwin-x64@0.25.9'
- '@esbuild/freebsd-arm64@0.25.9'
- '@esbuild/freebsd-x64@0.25.9'
- '@esbuild/linux-arm64@0.25.9'
- '@esbuild/linux-arm@0.25.9'
- '@esbuild/linux-ia32@0.25.9'
- '@esbuild/linux-loong64@0.25.9'
- '@esbuild/linux-mips64el@0.25.9'
- '@esbuild/linux-ppc64@0.25.9'
- '@esbuild/linux-riscv64@0.25.9'
- '@esbuild/linux-s390x@0.25.9'
- '@esbuild/netbsd-arm64@0.25.9'
- '@esbuild/netbsd-x64@0.25.9'
- '@esbuild/openbsd-arm64@0.25.9'
- '@esbuild/openbsd-x64@0.25.9'
- '@esbuild/openharmony-arm64@0.25.9'
- '@esbuild/sunos-x64@0.25.9'
- '@esbuild/win32-arm64@0.25.9'
- '@esbuild/win32-ia32@0.25.9'
- '@esbuild/win32-x64@0.25.9'
- fsevents@2.3.3
storeDir: /projects/.pnpm-store/v10
virtualStoreDir: .pnpm
virtualStoreDirMaxLength: 120

25
node_modules/.pnpm-workspace-state.json generated vendored Normal file
View File

@ -0,0 +1,25 @@
{
"lastValidatedTimestamp": 1757347442246,
"projects": {},
"pnpmfileExists": false,
"settings": {
"autoInstallPeers": true,
"dedupeDirectDeps": false,
"dedupeInjectedDeps": true,
"dedupePeerDependents": true,
"dev": true,
"excludeLinksFromLockfile": false,
"hoistPattern": [
"*"
],
"hoistWorkspacePackages": true,
"injectWorkspacePackages": false,
"linkWorkspacePackages": false,
"nodeLinker": "isolated",
"optional": true,
"preferWorkspacePackages": false,
"production": true,
"publicHoistPattern": []
},
"filteredInstall": false
}

View File

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

View File

@ -0,0 +1,289 @@
# Source Map Support
[![NPM version](https://img.shields.io/npm/v/@cspotcode/source-map-support.svg?style=flat)](https://npmjs.org/package/@cspotcode/source-map-support)
[![NPM downloads](https://img.shields.io/npm/dm/@cspotcode/source-map-support.svg?style=flat)](https://npmjs.org/package/@cspotcode/source-map-support)
[![Build status](https://img.shields.io/github/workflow/status/cspotcode/node-source-map-support/Continuous%20Integration)](https://github.com/cspotcode/node-source-map-support/actions?query=workflow%3A%22Continuous+Integration%22)
This module provides source map support for stack traces in node via the [V8 stack trace API](https://github.com/v8/v8/wiki/Stack-Trace-API). It uses the [source-map](https://github.com/mozilla/source-map) module to replace the paths and line numbers of source-mapped files with their original paths and line numbers. The output mimics node's stack trace format with the goal of making every compile-to-JS language more of a first-class citizen. Source maps are completely general (not specific to any one language) so you can use source maps with multiple compile-to-JS languages in the same node process.
## Installation and Usage
#### Node support
```
$ npm install @cspotcode/source-map-support
```
Source maps can be generated using libraries such as [source-map-index-generator](https://github.com/twolfson/source-map-index-generator). Once you have a valid source map, place a source mapping comment somewhere in the file (usually done automatically or with an option by your transpiler):
```
//# sourceMappingURL=path/to/source.map
```
If multiple sourceMappingURL comments exist in one file, the last sourceMappingURL comment will be
respected (e.g. if a file mentions the comment in code, or went through multiple transpilers).
The path should either be absolute or relative to the compiled file.
From here you have two options.
##### CLI Usage
```bash
node -r @cspotcode/source-map-support/register compiled.js
# Or to enable hookRequire
node -r @cspotcode/source-map-support/register-hook-require compiled.js
```
##### Programmatic Usage
Put the following line at the top of the compiled file.
```js
require('@cspotcode/source-map-support').install();
```
It is also possible to install the source map support directly by
requiring the `register` module which can be handy with ES6:
```js
import '@cspotcode/source-map-support/register'
// Instead of:
import sourceMapSupport from '@cspotcode/source-map-support'
sourceMapSupport.install()
```
Note: if you're using babel-register, it includes source-map-support already.
It is also very useful with Mocha:
```
$ mocha --require @cspotcode/source-map-support/register tests/
```
#### Browser support
This library also works in Chrome. While the DevTools console already supports source maps, the V8 engine doesn't and `Error.prototype.stack` will be incorrect without this library. Everything will just work if you deploy your source files using [browserify](http://browserify.org/). Just make sure to pass the `--debug` flag to the browserify command so your source maps are included in the bundled code.
This library also works if you use another build process or just include the source files directly. In this case, include the file `browser-source-map-support.js` in your page and call `sourceMapSupport.install()`. It contains the whole library already bundled for the browser using browserify.
```html
<script src="browser-source-map-support.js"></script>
<script>sourceMapSupport.install();</script>
```
This library also works if you use AMD (Asynchronous Module Definition), which is used in tools like [RequireJS](http://requirejs.org/). Just list `browser-source-map-support` as a dependency:
```html
<script>
define(['browser-source-map-support'], function(sourceMapSupport) {
sourceMapSupport.install();
});
</script>
```
## Options
This module installs two things: a change to the `stack` property on `Error` objects and a handler for uncaught exceptions that mimics node's default exception handler (the handler can be seen in the demos below). You may want to disable the handler if you have your own uncaught exception handler. This can be done by passing an argument to the installer:
```js
require('@cspotcode/source-map-support').install({
handleUncaughtExceptions: false
});
```
This module loads source maps from the filesystem by default. You can provide alternate loading behavior through a callback as shown below. For example, [Meteor](https://github.com/meteor) keeps all source maps cached in memory to avoid disk access.
```js
require('@cspotcode/source-map-support').install({
retrieveSourceMap: function(source) {
if (source === 'compiled.js') {
return {
url: 'original.js',
map: fs.readFileSync('compiled.js.map', 'utf8')
};
}
return null;
}
});
```
The module will by default assume a browser environment if XMLHttpRequest and window are defined. If either of these do not exist it will instead assume a node environment.
In some rare cases, e.g. when running a browser emulation and where both variables are also set, you can explictly specify the environment to be either 'browser' or 'node'.
```js
require('@cspotcode/source-map-support').install({
environment: 'node'
});
```
To support files with inline source maps, the `hookRequire` options can be specified, which will monitor all source files for inline source maps.
```js
require('@cspotcode/source-map-support').install({
hookRequire: true
});
```
This monkey patches the `require` module loading chain, so is not enabled by default and is not recommended for any sort of production usage.
## Demos
#### Basic Demo
original.js:
```js
throw new Error('test'); // This is the original code
```
compiled.js:
```js
require('@cspotcode/source-map-support').install();
throw new Error('test'); // This is the compiled code
// The next line defines the sourceMapping.
//# sourceMappingURL=compiled.js.map
```
compiled.js.map:
```json
{
"version": 3,
"file": "compiled.js",
"sources": ["original.js"],
"names": [],
"mappings": ";;AAAA,MAAM,IAAI"
}
```
Run compiled.js using node (notice how the stack trace uses original.js instead of compiled.js):
```
$ node compiled.js
original.js:1
throw new Error('test'); // This is the original code
^
Error: test
at Object.<anonymous> (original.js:1:7)
at Module._compile (module.js:456:26)
at Object.Module._extensions..js (module.js:474:10)
at Module.load (module.js:356:32)
at Function.Module._load (module.js:312:12)
at Function.Module.runMain (module.js:497:10)
at startup (node.js:119:16)
at node.js:901:3
```
#### TypeScript Demo
demo.ts:
```typescript
declare function require(name: string);
require('@cspotcode/source-map-support').install();
class Foo {
constructor() { this.bar(); }
bar() { throw new Error('this is a demo'); }
}
new Foo();
```
Compile and run the file using the TypeScript compiler from the terminal:
```
$ npm install source-map-support typescript
$ node_modules/typescript/bin/tsc -sourcemap demo.ts
$ node demo.js
demo.ts:5
bar() { throw new Error('this is a demo'); }
^
Error: this is a demo
at Foo.bar (demo.ts:5:17)
at new Foo (demo.ts:4:24)
at Object.<anonymous> (demo.ts:7:1)
at Module._compile (module.js:456:26)
at Object.Module._extensions..js (module.js:474:10)
at Module.load (module.js:356:32)
at Function.Module._load (module.js:312:12)
at Function.Module.runMain (module.js:497:10)
at startup (node.js:119:16)
at node.js:901:3
```
There is also the option to use `-r source-map-support/register` with typescript, without the need add the `require('@cspotcode/source-map-support').install()` in the code base:
```
$ npm install source-map-support typescript
$ node_modules/typescript/bin/tsc -sourcemap demo.ts
$ node -r source-map-support/register demo.js
demo.ts:5
bar() { throw new Error('this is a demo'); }
^
Error: this is a demo
at Foo.bar (demo.ts:5:17)
at new Foo (demo.ts:4:24)
at Object.<anonymous> (demo.ts:7:1)
at Module._compile (module.js:456:26)
at Object.Module._extensions..js (module.js:474:10)
at Module.load (module.js:356:32)
at Function.Module._load (module.js:312:12)
at Function.Module.runMain (module.js:497:10)
at startup (node.js:119:16)
at node.js:901:3
```
#### CoffeeScript Demo
demo.coffee:
```coffee
require('@cspotcode/source-map-support').install()
foo = ->
bar = -> throw new Error 'this is a demo'
bar()
foo()
```
Compile and run the file using the CoffeeScript compiler from the terminal:
```sh
$ npm install @cspotcode/source-map-support coffeescript
$ node_modules/.bin/coffee --map --compile demo.coffee
$ node demo.js
demo.coffee:3
bar = -> throw new Error 'this is a demo'
^
Error: this is a demo
at bar (demo.coffee:3:22)
at foo (demo.coffee:4:3)
at Object.<anonymous> (demo.coffee:5:1)
at Object.<anonymous> (demo.coffee:1:1)
at Module._compile (module.js:456:26)
at Object.Module._extensions..js (module.js:474:10)
at Module.load (module.js:356:32)
at Function.Module._load (module.js:312:12)
at Function.Module.runMain (module.js:497:10)
at startup (node.js:119:16)
```
## Tests
This repo contains both automated tests for node and manual tests for the browser. The automated tests can be run using mocha (type `mocha` in the root directory). To run the manual tests:
* Build the tests using `build.js`
* Launch the HTTP server (`npm run serve-tests`) and visit
* http://127.0.0.1:1336/amd-test
* http://127.0.0.1:1336/browser-test
* http://127.0.0.1:1336/browserify-test - **Currently not working** due to a bug with browserify (see [pull request #66](https://github.com/evanw/node-source-map-support/pull/66) for details).
* For `header-test`, run `server.js` inside that directory and visit http://127.0.0.1:1337/
## License
This code is available under the [MIT license](http://opensource.org/licenses/MIT).

View File

@ -0,0 +1,114 @@
/*
* Support for source maps in V8 stack traces
* https://github.com/evanw/node-source-map-support
*/
/*
The buffer module from node.js, for the browser.
@author Feross Aboukhadijeh <feross@feross.org> <http://feross.org>
license MIT
*/
(this.define||function(R,U){this.sourceMapSupport=U()})("browser-source-map-support",function(R){(function e(C,J,A){function p(f,c){if(!J[f]){if(!C[f]){var l="function"==typeof require&&require;if(!c&&l)return l(f,!0);if(t)return t(f,!0);throw Error("Cannot find module '"+f+"'");}l=J[f]={exports:{}};C[f][0].call(l.exports,function(q){var r=C[f][1][q];return p(r?r:q)},l,l.exports,e,C,J,A)}return J[f].exports}for(var t="function"==typeof require&&require,m=0;m<A.length;m++)p(A[m]);return p})({1:[function(C,
J,A){R=C("./source-map-support")},{"./source-map-support":21}],2:[function(C,J,A){(function(e){function p(m){m=m.charCodeAt(0);if(43===m)return 62;if(47===m)return 63;if(48>m)return-1;if(58>m)return m-48+52;if(91>m)return m-65;if(123>m)return m-97+26}var t="undefined"!==typeof Uint8Array?Uint8Array:Array;e.toByteArray=function(m){function f(d){q[k++]=d}if(0<m.length%4)throw Error("Invalid string. Length must be a multiple of 4");var c=m.length;var l="="===m.charAt(c-2)?2:"="===m.charAt(c-1)?1:0;var q=
new t(3*m.length/4-l);var r=0<l?m.length-4:m.length;var k=0;for(c=0;c<r;c+=4){var u=p(m.charAt(c))<<18|p(m.charAt(c+1))<<12|p(m.charAt(c+2))<<6|p(m.charAt(c+3));f((u&16711680)>>16);f((u&65280)>>8);f(u&255)}2===l?(u=p(m.charAt(c))<<2|p(m.charAt(c+1))>>4,f(u&255)):1===l&&(u=p(m.charAt(c))<<10|p(m.charAt(c+1))<<4|p(m.charAt(c+2))>>2,f(u>>8&255),f(u&255));return q};e.fromByteArray=function(m){var f=m.length%3,c="",l;var q=0;for(l=m.length-f;q<l;q+=3){var r=(m[q]<<16)+(m[q+1]<<8)+m[q+2];r="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/".charAt(r>>
18&63)+"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/".charAt(r>>12&63)+"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/".charAt(r>>6&63)+"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/".charAt(r&63);c+=r}switch(f){case 1:r=m[m.length-1];c+="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/".charAt(r>>2);c+="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/".charAt(r<<4&63);c+="==";break;case 2:r=(m[m.length-2]<<8)+
m[m.length-1],c+="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/".charAt(r>>10),c+="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/".charAt(r>>4&63),c+="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/".charAt(r<<2&63),c+="="}return c}})("undefined"===typeof A?this.base64js={}:A)},{}],3:[function(C,J,A){},{}],4:[function(C,J,A){(function(e){var p=Object.prototype.toString,t="function"===typeof e.alloc&&"function"===typeof e.allocUnsafe&&"function"===
typeof e.from;J.exports=function(m,f,c){if("number"===typeof m)throw new TypeError('"value" argument must not be a number');if("ArrayBuffer"===p.call(m).slice(8,-1)){f>>>=0;var l=m.byteLength-f;if(0>l)throw new RangeError("'offset' is out of bounds");if(void 0===c)c=l;else if(c>>>=0,c>l)throw new RangeError("'length' is out of bounds");return t?e.from(m.slice(f,f+c)):new e(new Uint8Array(m.slice(f,f+c)))}if("string"===typeof m){c=f;if("string"!==typeof c||""===c)c="utf8";if(!e.isEncoding(c))throw new TypeError('"encoding" must be a valid string encoding');
return t?e.from(m,c):new e(m,c)}return t?e.from(m):new e(m)}}).call(this,C("buffer").Buffer)},{buffer:5}],5:[function(C,J,A){function e(a,b,h){if(!(this instanceof e))return new e(a,b,h);var w=typeof a;if("number"===w)var y=0<a?a>>>0:0;else if("string"===w){if("base64"===b)for(a=(a.trim?a.trim():a.replace(/^\s+|\s+$/g,"")).replace(L,"");0!==a.length%4;)a+="=";y=e.byteLength(a,b)}else if("object"===w&&null!==a)"Buffer"===a.type&&z(a.data)&&(a=a.data),y=0<+a.length?Math.floor(+a.length):0;else throw new TypeError("must start with number, buffer, array or string");
if(this.length>G)throw new RangeError("Attempt to allocate Buffer larger than maximum size: 0x"+G.toString(16)+" bytes");if(e.TYPED_ARRAY_SUPPORT)var I=e._augment(new Uint8Array(y));else I=this,I.length=y,I._isBuffer=!0;if(e.TYPED_ARRAY_SUPPORT&&"number"===typeof a.byteLength)I._set(a);else{var K=a;if(z(K)||e.isBuffer(K)||K&&"object"===typeof K&&"number"===typeof K.length)if(e.isBuffer(a))for(b=0;b<y;b++)I[b]=a.readUInt8(b);else for(b=0;b<y;b++)I[b]=(a[b]%256+256)%256;else if("string"===w)I.write(a,
0,b);else if("number"===w&&!e.TYPED_ARRAY_SUPPORT&&!h)for(b=0;b<y;b++)I[b]=0}return I}function p(a,b,h){var w="";for(h=Math.min(a.length,h);b<h;b++)w+=String.fromCharCode(a[b]);return w}function t(a,b,h){if(0!==a%1||0>a)throw new RangeError("offset is not uint");if(a+b>h)throw new RangeError("Trying to access beyond buffer length");}function m(a,b,h,w,y,I){if(!e.isBuffer(a))throw new TypeError("buffer must be a Buffer instance");if(b>y||b<I)throw new TypeError("value is out of bounds");if(h+w>a.length)throw new TypeError("index out of range");
}function f(a,b,h,w){0>b&&(b=65535+b+1);for(var y=0,I=Math.min(a.length-h,2);y<I;y++)a[h+y]=(b&255<<8*(w?y:1-y))>>>8*(w?y:1-y)}function c(a,b,h,w){0>b&&(b=4294967295+b+1);for(var y=0,I=Math.min(a.length-h,4);y<I;y++)a[h+y]=b>>>8*(w?y:3-y)&255}function l(a,b,h,w,y,I){if(b>y||b<I)throw new TypeError("value is out of bounds");if(h+w>a.length)throw new TypeError("index out of range");}function q(a,b,h,w,y){y||l(a,b,h,4,3.4028234663852886E38,-3.4028234663852886E38);v.write(a,b,h,w,23,4);return h+4}function r(a,
b,h,w,y){y||l(a,b,h,8,1.7976931348623157E308,-1.7976931348623157E308);v.write(a,b,h,w,52,8);return h+8}function k(a){for(var b=[],h=0;h<a.length;h++){var w=a.charCodeAt(h);if(127>=w)b.push(w);else{var y=h;55296<=w&&57343>=w&&h++;w=encodeURIComponent(a.slice(y,h+1)).substr(1).split("%");for(y=0;y<w.length;y++)b.push(parseInt(w[y],16))}}return b}function u(a){for(var b=[],h=0;h<a.length;h++)b.push(a.charCodeAt(h)&255);return b}function d(a,b,h,w,y){y&&(w-=w%y);for(y=0;y<w&&!(y+h>=b.length||y>=a.length);y++)b[y+
h]=a[y];return y}function g(a){try{return decodeURIComponent(a)}catch(b){return String.fromCharCode(65533)}}var n=C("base64-js"),v=C("ieee754"),z=C("is-array");A.Buffer=e;A.SlowBuffer=e;A.INSPECT_MAX_BYTES=50;e.poolSize=8192;var G=1073741823;e.TYPED_ARRAY_SUPPORT=function(){try{var a=new ArrayBuffer(0),b=new Uint8Array(a);b.foo=function(){return 42};return 42===b.foo()&&"function"===typeof b.subarray&&0===(new Uint8Array(1)).subarray(1,1).byteLength}catch(h){return!1}}();e.isBuffer=function(a){return!(null==
a||!a._isBuffer)};e.compare=function(a,b){if(!e.isBuffer(a)||!e.isBuffer(b))throw new TypeError("Arguments must be Buffers");for(var h=a.length,w=b.length,y=0,I=Math.min(h,w);y<I&&a[y]===b[y];y++);y!==I&&(h=a[y],w=b[y]);return h<w?-1:w<h?1:0};e.isEncoding=function(a){switch(String(a).toLowerCase()){case "hex":case "utf8":case "utf-8":case "ascii":case "binary":case "base64":case "raw":case "ucs2":case "ucs-2":case "utf16le":case "utf-16le":return!0;default:return!1}};e.concat=function(a,b){if(!z(a))throw new TypeError("Usage: Buffer.concat(list[, length])");
if(0===a.length)return new e(0);if(1===a.length)return a[0];var h;if(void 0===b)for(h=b=0;h<a.length;h++)b+=a[h].length;var w=new e(b),y=0;for(h=0;h<a.length;h++){var I=a[h];I.copy(w,y);y+=I.length}return w};e.byteLength=function(a,b){a+="";switch(b||"utf8"){case "ascii":case "binary":case "raw":var h=a.length;break;case "ucs2":case "ucs-2":case "utf16le":case "utf-16le":h=2*a.length;break;case "hex":h=a.length>>>1;break;case "utf8":case "utf-8":h=k(a).length;break;case "base64":h=n.toByteArray(a).length;
break;default:h=a.length}return h};e.prototype.length=void 0;e.prototype.parent=void 0;e.prototype.toString=function(a,b,h){var w=!1;b>>>=0;h=void 0===h||Infinity===h?this.length:h>>>0;a||(a="utf8");0>b&&(b=0);h>this.length&&(h=this.length);if(h<=b)return"";for(;;)switch(a){case "hex":a=b;b=h;h=this.length;if(!a||0>a)a=0;if(!b||0>b||b>h)b=h;w="";for(h=a;h<b;h++)a=w,w=this[h],w=16>w?"0"+w.toString(16):w.toString(16),w=a+w;return w;case "utf8":case "utf-8":w=a="";for(h=Math.min(this.length,h);b<h;b++)127>=
this[b]?(a+=g(w)+String.fromCharCode(this[b]),w=""):w+="%"+this[b].toString(16);return a+g(w);case "ascii":return p(this,b,h);case "binary":return p(this,b,h);case "base64":return b=0===b&&h===this.length?n.fromByteArray(this):n.fromByteArray(this.slice(b,h)),b;case "ucs2":case "ucs-2":case "utf16le":case "utf-16le":b=this.slice(b,h);h="";for(a=0;a<b.length;a+=2)h+=String.fromCharCode(b[a]+256*b[a+1]);return h;default:if(w)throw new TypeError("Unknown encoding: "+a);a=(a+"").toLowerCase();w=!0}};
e.prototype.equals=function(a){if(!e.isBuffer(a))throw new TypeError("Argument must be a Buffer");return 0===e.compare(this,a)};e.prototype.inspect=function(){var a="",b=A.INSPECT_MAX_BYTES;0<this.length&&(a=this.toString("hex",0,b).match(/.{2}/g).join(" "),this.length>b&&(a+=" ... "));return"<Buffer "+a+">"};e.prototype.compare=function(a){if(!e.isBuffer(a))throw new TypeError("Argument must be a Buffer");return e.compare(this,a)};e.prototype.get=function(a){console.log(".get() is deprecated. Access using array indexes instead.");
return this.readUInt8(a)};e.prototype.set=function(a,b){console.log(".set() is deprecated. Access using array indexes instead.");return this.writeUInt8(a,b)};e.prototype.write=function(a,b,h,w){if(isFinite(b))isFinite(h)||(w=h,h=void 0);else{var y=w;w=b;b=h;h=y}b=Number(b)||0;y=this.length-b;h?(h=Number(h),h>y&&(h=y)):h=y;w=String(w||"utf8").toLowerCase();switch(w){case "hex":b=Number(b)||0;w=this.length-b;h?(h=Number(h),h>w&&(h=w)):h=w;w=a.length;if(0!==w%2)throw Error("Invalid hex string");h>w/
2&&(h=w/2);for(w=0;w<h;w++){y=parseInt(a.substr(2*w,2),16);if(isNaN(y))throw Error("Invalid hex string");this[b+w]=y}a=w;break;case "utf8":case "utf-8":a=d(k(a),this,b,h);break;case "ascii":a=d(u(a),this,b,h);break;case "binary":a=d(u(a),this,b,h);break;case "base64":a=d(n.toByteArray(a),this,b,h);break;case "ucs2":case "ucs-2":case "utf16le":case "utf-16le":y=[];for(var I=0;I<a.length;I++){var K=a.charCodeAt(I);w=K>>8;K%=256;y.push(K);y.push(w)}a=d(y,this,b,h,2);break;default:throw new TypeError("Unknown encoding: "+
w);}return a};e.prototype.toJSON=function(){return{type:"Buffer",data:Array.prototype.slice.call(this._arr||this,0)}};e.prototype.slice=function(a,b){var h=this.length;a=~~a;b=void 0===b?h:~~b;0>a?(a+=h,0>a&&(a=0)):a>h&&(a=h);0>b?(b+=h,0>b&&(b=0)):b>h&&(b=h);b<a&&(b=a);if(e.TYPED_ARRAY_SUPPORT)return e._augment(this.subarray(a,b));h=b-a;for(var w=new e(h,void 0,!0),y=0;y<h;y++)w[y]=this[y+a];return w};e.prototype.readUInt8=function(a,b){b||t(a,1,this.length);return this[a]};e.prototype.readUInt16LE=
function(a,b){b||t(a,2,this.length);return this[a]|this[a+1]<<8};e.prototype.readUInt16BE=function(a,b){b||t(a,2,this.length);return this[a]<<8|this[a+1]};e.prototype.readUInt32LE=function(a,b){b||t(a,4,this.length);return(this[a]|this[a+1]<<8|this[a+2]<<16)+16777216*this[a+3]};e.prototype.readUInt32BE=function(a,b){b||t(a,4,this.length);return 16777216*this[a]+(this[a+1]<<16|this[a+2]<<8|this[a+3])};e.prototype.readInt8=function(a,b){b||t(a,1,this.length);return this[a]&128?-1*(255-this[a]+1):this[a]};
e.prototype.readInt16LE=function(a,b){b||t(a,2,this.length);var h=this[a]|this[a+1]<<8;return h&32768?h|4294901760:h};e.prototype.readInt16BE=function(a,b){b||t(a,2,this.length);var h=this[a+1]|this[a]<<8;return h&32768?h|4294901760:h};e.prototype.readInt32LE=function(a,b){b||t(a,4,this.length);return this[a]|this[a+1]<<8|this[a+2]<<16|this[a+3]<<24};e.prototype.readInt32BE=function(a,b){b||t(a,4,this.length);return this[a]<<24|this[a+1]<<16|this[a+2]<<8|this[a+3]};e.prototype.readFloatLE=function(a,
b){b||t(a,4,this.length);return v.read(this,a,!0,23,4)};e.prototype.readFloatBE=function(a,b){b||t(a,4,this.length);return v.read(this,a,!1,23,4)};e.prototype.readDoubleLE=function(a,b){b||t(a,8,this.length);return v.read(this,a,!0,52,8)};e.prototype.readDoubleBE=function(a,b){b||t(a,8,this.length);return v.read(this,a,!1,52,8)};e.prototype.writeUInt8=function(a,b,h){a=+a;b>>>=0;h||m(this,a,b,1,255,0);e.TYPED_ARRAY_SUPPORT||(a=Math.floor(a));this[b]=a;return b+1};e.prototype.writeUInt16LE=function(a,
b,h){a=+a;b>>>=0;h||m(this,a,b,2,65535,0);e.TYPED_ARRAY_SUPPORT?(this[b]=a,this[b+1]=a>>>8):f(this,a,b,!0);return b+2};e.prototype.writeUInt16BE=function(a,b,h){a=+a;b>>>=0;h||m(this,a,b,2,65535,0);e.TYPED_ARRAY_SUPPORT?(this[b]=a>>>8,this[b+1]=a):f(this,a,b,!1);return b+2};e.prototype.writeUInt32LE=function(a,b,h){a=+a;b>>>=0;h||m(this,a,b,4,4294967295,0);e.TYPED_ARRAY_SUPPORT?(this[b+3]=a>>>24,this[b+2]=a>>>16,this[b+1]=a>>>8,this[b]=a):c(this,a,b,!0);return b+4};e.prototype.writeUInt32BE=function(a,
b,h){a=+a;b>>>=0;h||m(this,a,b,4,4294967295,0);e.TYPED_ARRAY_SUPPORT?(this[b]=a>>>24,this[b+1]=a>>>16,this[b+2]=a>>>8,this[b+3]=a):c(this,a,b,!1);return b+4};e.prototype.writeInt8=function(a,b,h){a=+a;b>>>=0;h||m(this,a,b,1,127,-128);e.TYPED_ARRAY_SUPPORT||(a=Math.floor(a));0>a&&(a=255+a+1);this[b]=a;return b+1};e.prototype.writeInt16LE=function(a,b,h){a=+a;b>>>=0;h||m(this,a,b,2,32767,-32768);e.TYPED_ARRAY_SUPPORT?(this[b]=a,this[b+1]=a>>>8):f(this,a,b,!0);return b+2};e.prototype.writeInt16BE=function(a,
b,h){a=+a;b>>>=0;h||m(this,a,b,2,32767,-32768);e.TYPED_ARRAY_SUPPORT?(this[b]=a>>>8,this[b+1]=a):f(this,a,b,!1);return b+2};e.prototype.writeInt32LE=function(a,b,h){a=+a;b>>>=0;h||m(this,a,b,4,2147483647,-2147483648);e.TYPED_ARRAY_SUPPORT?(this[b]=a,this[b+1]=a>>>8,this[b+2]=a>>>16,this[b+3]=a>>>24):c(this,a,b,!0);return b+4};e.prototype.writeInt32BE=function(a,b,h){a=+a;b>>>=0;h||m(this,a,b,4,2147483647,-2147483648);0>a&&(a=4294967295+a+1);e.TYPED_ARRAY_SUPPORT?(this[b]=a>>>24,this[b+1]=a>>>16,this[b+
2]=a>>>8,this[b+3]=a):c(this,a,b,!1);return b+4};e.prototype.writeFloatLE=function(a,b,h){return q(this,a,b,!0,h)};e.prototype.writeFloatBE=function(a,b,h){return q(this,a,b,!1,h)};e.prototype.writeDoubleLE=function(a,b,h){return r(this,a,b,!0,h)};e.prototype.writeDoubleBE=function(a,b,h){return r(this,a,b,!1,h)};e.prototype.copy=function(a,b,h,w){h||(h=0);w||0===w||(w=this.length);b||(b=0);if(w!==h&&0!==a.length&&0!==this.length){if(w<h)throw new TypeError("sourceEnd < sourceStart");if(0>b||b>=a.length)throw new TypeError("targetStart out of bounds");
if(0>h||h>=this.length)throw new TypeError("sourceStart out of bounds");if(0>w||w>this.length)throw new TypeError("sourceEnd out of bounds");w>this.length&&(w=this.length);a.length-b<w-h&&(w=a.length-b+h);w-=h;if(1E3>w||!e.TYPED_ARRAY_SUPPORT)for(var y=0;y<w;y++)a[y+b]=this[y+h];else a._set(this.subarray(h,h+w),b)}};e.prototype.fill=function(a,b,h){a||(a=0);b||(b=0);h||(h=this.length);if(h<b)throw new TypeError("end < start");if(h!==b&&0!==this.length){if(0>b||b>=this.length)throw new TypeError("start out of bounds");
if(0>h||h>this.length)throw new TypeError("end out of bounds");if("number"===typeof a)for(;b<h;b++)this[b]=a;else{a=k(a.toString());for(var w=a.length;b<h;b++)this[b]=a[b%w]}return this}};e.prototype.toArrayBuffer=function(){if("undefined"!==typeof Uint8Array){if(e.TYPED_ARRAY_SUPPORT)return(new e(this)).buffer;for(var a=new Uint8Array(this.length),b=0,h=a.length;b<h;b+=1)a[b]=this[b];return a.buffer}throw new TypeError("Buffer.toArrayBuffer not supported in this browser");};var D=e.prototype;e._augment=
function(a){a.constructor=e;a._isBuffer=!0;a._get=a.get;a._set=a.set;a.get=D.get;a.set=D.set;a.write=D.write;a.toString=D.toString;a.toLocaleString=D.toString;a.toJSON=D.toJSON;a.equals=D.equals;a.compare=D.compare;a.copy=D.copy;a.slice=D.slice;a.readUInt8=D.readUInt8;a.readUInt16LE=D.readUInt16LE;a.readUInt16BE=D.readUInt16BE;a.readUInt32LE=D.readUInt32LE;a.readUInt32BE=D.readUInt32BE;a.readInt8=D.readInt8;a.readInt16LE=D.readInt16LE;a.readInt16BE=D.readInt16BE;a.readInt32LE=D.readInt32LE;a.readInt32BE=
D.readInt32BE;a.readFloatLE=D.readFloatLE;a.readFloatBE=D.readFloatBE;a.readDoubleLE=D.readDoubleLE;a.readDoubleBE=D.readDoubleBE;a.writeUInt8=D.writeUInt8;a.writeUInt16LE=D.writeUInt16LE;a.writeUInt16BE=D.writeUInt16BE;a.writeUInt32LE=D.writeUInt32LE;a.writeUInt32BE=D.writeUInt32BE;a.writeInt8=D.writeInt8;a.writeInt16LE=D.writeInt16LE;a.writeInt16BE=D.writeInt16BE;a.writeInt32LE=D.writeInt32LE;a.writeInt32BE=D.writeInt32BE;a.writeFloatLE=D.writeFloatLE;a.writeFloatBE=D.writeFloatBE;a.writeDoubleLE=
D.writeDoubleLE;a.writeDoubleBE=D.writeDoubleBE;a.fill=D.fill;a.inspect=D.inspect;a.toArrayBuffer=D.toArrayBuffer;return a};var L=/[^+\/0-9A-z]/g},{"base64-js":2,ieee754:6,"is-array":7}],6:[function(C,J,A){A.read=function(e,p,t,m,f){var c=8*f-m-1;var l=(1<<c)-1,q=l>>1,r=-7;f=t?f-1:0;var k=t?-1:1,u=e[p+f];f+=k;t=u&(1<<-r)-1;u>>=-r;for(r+=c;0<r;t=256*t+e[p+f],f+=k,r-=8);c=t&(1<<-r)-1;t>>=-r;for(r+=m;0<r;c=256*c+e[p+f],f+=k,r-=8);if(0===t)t=1-q;else{if(t===l)return c?NaN:Infinity*(u?-1:1);c+=Math.pow(2,
m);t-=q}return(u?-1:1)*c*Math.pow(2,t-m)};A.write=function(e,p,t,m,f,c){var l,q=8*c-f-1,r=(1<<q)-1,k=r>>1,u=23===f?Math.pow(2,-24)-Math.pow(2,-77):0;c=m?0:c-1;var d=m?1:-1,g=0>p||0===p&&0>1/p?1:0;p=Math.abs(p);isNaN(p)||Infinity===p?(p=isNaN(p)?1:0,m=r):(m=Math.floor(Math.log(p)/Math.LN2),1>p*(l=Math.pow(2,-m))&&(m--,l*=2),p=1<=m+k?p+u/l:p+u*Math.pow(2,1-k),2<=p*l&&(m++,l/=2),m+k>=r?(p=0,m=r):1<=m+k?(p=(p*l-1)*Math.pow(2,f),m+=k):(p=p*Math.pow(2,k-1)*Math.pow(2,f),m=0));for(;8<=f;e[t+c]=p&255,c+=
d,p/=256,f-=8);m=m<<f|p;for(q+=f;0<q;e[t+c]=m&255,c+=d,m/=256,q-=8);e[t+c-d]|=128*g}},{}],7:[function(C,J,A){var e=Object.prototype.toString;J.exports=Array.isArray||function(p){return!!p&&"[object Array]"==e.call(p)}},{}],8:[function(C,J,A){(function(e){function p(c,l){for(var q=0,r=c.length-1;0<=r;r--){var k=c[r];"."===k?c.splice(r,1):".."===k?(c.splice(r,1),q++):q&&(c.splice(r,1),q--)}if(l)for(;q--;q)c.unshift("..");return c}function t(c,l){if(c.filter)return c.filter(l);for(var q=[],r=0;r<c.length;r++)l(c[r],
r,c)&&q.push(c[r]);return q}var m=/^(\/?|)([\s\S]*?)((?:\.{1,2}|[^\/]+?|)(\.[^.\/]*|))(?:[\/]*)$/;A.resolve=function(){for(var c="",l=!1,q=arguments.length-1;-1<=q&&!l;q--){var r=0<=q?arguments[q]:e.cwd();if("string"!==typeof r)throw new TypeError("Arguments to path.resolve must be strings");r&&(c=r+"/"+c,l="/"===r.charAt(0))}c=p(t(c.split("/"),function(k){return!!k}),!l).join("/");return(l?"/":"")+c||"."};A.normalize=function(c){var l=A.isAbsolute(c),q="/"===f(c,-1);(c=p(t(c.split("/"),function(r){return!!r}),
!l).join("/"))||l||(c=".");c&&q&&(c+="/");return(l?"/":"")+c};A.isAbsolute=function(c){return"/"===c.charAt(0)};A.join=function(){var c=Array.prototype.slice.call(arguments,0);return A.normalize(t(c,function(l,q){if("string"!==typeof l)throw new TypeError("Arguments to path.join must be strings");return l}).join("/"))};A.relative=function(c,l){function q(n){for(var v=0;v<n.length&&""===n[v];v++);for(var z=n.length-1;0<=z&&""===n[z];z--);return v>z?[]:n.slice(v,z-v+1)}c=A.resolve(c).substr(1);l=A.resolve(l).substr(1);
for(var r=q(c.split("/")),k=q(l.split("/")),u=Math.min(r.length,k.length),d=u,g=0;g<u;g++)if(r[g]!==k[g]){d=g;break}u=[];for(g=d;g<r.length;g++)u.push("..");u=u.concat(k.slice(d));return u.join("/")};A.sep="/";A.delimiter=":";A.dirname=function(c){var l=m.exec(c).slice(1);c=l[0];l=l[1];if(!c&&!l)return".";l&&(l=l.substr(0,l.length-1));return c+l};A.basename=function(c,l){var q=m.exec(c).slice(1)[2];l&&q.substr(-1*l.length)===l&&(q=q.substr(0,q.length-l.length));return q};A.extname=function(c){return m.exec(c).slice(1)[3]};
var f="b"==="ab".substr(-1)?function(c,l,q){return c.substr(l,q)}:function(c,l,q){0>l&&(l=c.length+l);return c.substr(l,q)}}).call(this,C("g5I+bs"))},{"g5I+bs":9}],9:[function(C,J,A){function e(){}C=J.exports={};C.nextTick=function(){if("undefined"!==typeof window&&window.setImmediate)return function(t){return window.setImmediate(t)};if("undefined"!==typeof window&&window.postMessage&&window.addEventListener){var p=[];window.addEventListener("message",function(t){var m=t.source;m!==window&&null!==
m||"process-tick"!==t.data||(t.stopPropagation(),0<p.length&&p.shift()())},!0);return function(t){p.push(t);window.postMessage("process-tick","*")}}return function(t){setTimeout(t,0)}}();C.title="browser";C.browser=!0;C.env={};C.argv=[];C.on=e;C.addListener=e;C.once=e;C.off=e;C.removeListener=e;C.removeAllListeners=e;C.emit=e;C.binding=function(p){throw Error("process.binding is not supported");};C.cwd=function(){return"/"};C.chdir=function(p){throw Error("process.chdir is not supported");}},{}],
10:[function(C,J,A){function e(){this._array=[];this._set=m?new Map:Object.create(null)}var p=C("./util"),t=Object.prototype.hasOwnProperty,m="undefined"!==typeof Map;e.fromArray=function(f,c){for(var l=new e,q=0,r=f.length;q<r;q++)l.add(f[q],c);return l};e.prototype.size=function(){return m?this._set.size:Object.getOwnPropertyNames(this._set).length};e.prototype.add=function(f,c){var l=m?f:p.toSetString(f),q=m?this.has(f):t.call(this._set,l),r=this._array.length;q&&!c||this._array.push(f);q||(m?
this._set.set(f,r):this._set[l]=r)};e.prototype.has=function(f){if(m)return this._set.has(f);f=p.toSetString(f);return t.call(this._set,f)};e.prototype.indexOf=function(f){if(m){var c=this._set.get(f);if(0<=c)return c}else if(c=p.toSetString(f),t.call(this._set,c))return this._set[c];throw Error('"'+f+'" is not in the set.');};e.prototype.at=function(f){if(0<=f&&f<this._array.length)return this._array[f];throw Error("No element indexed by "+f);};e.prototype.toArray=function(){return this._array.slice()};
A.ArraySet=e},{"./util":19}],11:[function(C,J,A){var e=C("./base64");A.encode=function(p){var t="",m=0>p?(-p<<1)+1:p<<1;do p=m&31,m>>>=5,0<m&&(p|=32),t+=e.encode(p);while(0<m);return t};A.decode=function(p,t,m){var f=p.length,c=0,l=0;do{if(t>=f)throw Error("Expected more digits in base 64 VLQ value.");var q=e.decode(p.charCodeAt(t++));if(-1===q)throw Error("Invalid base64 digit: "+p.charAt(t-1));var r=!!(q&32);q&=31;c+=q<<l;l+=5}while(r);p=c>>1;m.value=1===(c&1)?-p:p;m.rest=t}},{"./base64":12}],12:[function(C,
J,A){var e="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/".split("");A.encode=function(p){if(0<=p&&p<e.length)return e[p];throw new TypeError("Must be between 0 and 63: "+p);};A.decode=function(p){return 65<=p&&90>=p?p-65:97<=p&&122>=p?p-97+26:48<=p&&57>=p?p-48+52:43==p?62:47==p?63:-1}},{}],13:[function(C,J,A){function e(p,t,m,f,c,l){var q=Math.floor((t-p)/2)+p,r=c(m,f[q],!0);return 0===r?q:0<r?1<t-q?e(q,t,m,f,c,l):l==A.LEAST_UPPER_BOUND?t<f.length?t:-1:q:1<q-p?e(p,q,m,f,c,l):l==
A.LEAST_UPPER_BOUND?q:0>p?-1:p}A.GREATEST_LOWER_BOUND=1;A.LEAST_UPPER_BOUND=2;A.search=function(p,t,m,f){if(0===t.length)return-1;p=e(-1,t.length,p,t,m,f||A.GREATEST_LOWER_BOUND);if(0>p)return-1;for(;0<=p-1&&0===m(t[p],t[p-1],!0);)--p;return p}},{}],14:[function(C,J,A){function e(){this._array=[];this._sorted=!0;this._last={generatedLine:-1,generatedColumn:0}}var p=C("./util");e.prototype.unsortedForEach=function(t,m){this._array.forEach(t,m)};e.prototype.add=function(t){var m=this._last,f=m.generatedLine,
c=t.generatedLine,l=m.generatedColumn,q=t.generatedColumn;c>f||c==f&&q>=l||0>=p.compareByGeneratedPositionsInflated(m,t)?this._last=t:this._sorted=!1;this._array.push(t)};e.prototype.toArray=function(){this._sorted||(this._array.sort(p.compareByGeneratedPositionsInflated),this._sorted=!0);return this._array};A.MappingList=e},{"./util":19}],15:[function(C,J,A){function e(t,m,f){var c=t[m];t[m]=t[f];t[f]=c}function p(t,m,f,c){if(f<c){var l=f-1;e(t,Math.round(f+Math.random()*(c-f)),c);for(var q=t[c],
r=f;r<c;r++)0>=m(t[r],q)&&(l+=1,e(t,l,r));e(t,l+1,r);l+=1;p(t,m,f,l-1);p(t,m,l+1,c)}}A.quickSort=function(t,m){p(t,m,0,t.length-1)}},{}],16:[function(C,J,A){function e(k,u){var d=k;"string"===typeof k&&(d=f.parseSourceMapInput(k));return null!=d.sections?new m(d,u):new p(d,u)}function p(k,u){var d=k;"string"===typeof k&&(d=f.parseSourceMapInput(k));var g=f.getArg(d,"version"),n=f.getArg(d,"sources"),v=f.getArg(d,"names",[]),z=f.getArg(d,"sourceRoot",null),G=f.getArg(d,"sourcesContent",null),D=f.getArg(d,
"mappings");d=f.getArg(d,"file",null);if(g!=this._version)throw Error("Unsupported version: "+g);z&&(z=f.normalize(z));n=n.map(String).map(f.normalize).map(function(L){return z&&f.isAbsolute(z)&&f.isAbsolute(L)?f.relative(z,L):L});this._names=l.fromArray(v.map(String),!0);this._sources=l.fromArray(n,!0);this.sourceRoot=z;this.sourcesContent=G;this._mappings=D;this._sourceMapURL=u;this.file=d}function t(){this.generatedColumn=this.generatedLine=0;this.name=this.originalColumn=this.originalLine=this.source=
null}function m(k,u){var d=k;"string"===typeof k&&(d=f.parseSourceMapInput(k));var g=f.getArg(d,"version");d=f.getArg(d,"sections");if(g!=this._version)throw Error("Unsupported version: "+g);this._sources=new l;this._names=new l;var n={line:-1,column:0};this._sections=d.map(function(v){if(v.url)throw Error("Support for url field in sections not implemented.");var z=f.getArg(v,"offset"),G=f.getArg(z,"line"),D=f.getArg(z,"column");if(G<n.line||G===n.line&&D<n.column)throw Error("Section offsets must be ordered and non-overlapping.");
n=z;return{generatedOffset:{generatedLine:G+1,generatedColumn:D+1},consumer:new e(f.getArg(v,"map"),u)}})}var f=C("./util"),c=C("./binary-search"),l=C("./array-set").ArraySet,q=C("./base64-vlq"),r=C("./quick-sort").quickSort;e.fromSourceMap=function(k){return p.fromSourceMap(k)};e.prototype._version=3;e.prototype.__generatedMappings=null;Object.defineProperty(e.prototype,"_generatedMappings",{configurable:!0,enumerable:!0,get:function(){this.__generatedMappings||this._parseMappings(this._mappings,
this.sourceRoot);return this.__generatedMappings}});e.prototype.__originalMappings=null;Object.defineProperty(e.prototype,"_originalMappings",{configurable:!0,enumerable:!0,get:function(){this.__originalMappings||this._parseMappings(this._mappings,this.sourceRoot);return this.__originalMappings}});e.prototype._charIsMappingSeparator=function(k,u){var d=k.charAt(u);return";"===d||","===d};e.prototype._parseMappings=function(k,u){throw Error("Subclasses must implement _parseMappings");};e.GENERATED_ORDER=
1;e.ORIGINAL_ORDER=2;e.GREATEST_LOWER_BOUND=1;e.LEAST_UPPER_BOUND=2;e.prototype.eachMapping=function(k,u,d){u=u||null;switch(d||e.GENERATED_ORDER){case e.GENERATED_ORDER:d=this._generatedMappings;break;case e.ORIGINAL_ORDER:d=this._originalMappings;break;default:throw Error("Unknown order of iteration.");}var g=this.sourceRoot;d.map(function(n){var v=null===n.source?null:this._sources.at(n.source);v=f.computeSourceURL(g,v,this._sourceMapURL);return{source:v,generatedLine:n.generatedLine,generatedColumn:n.generatedColumn,
originalLine:n.originalLine,originalColumn:n.originalColumn,name:null===n.name?null:this._names.at(n.name)}},this).forEach(k,u)};e.prototype.allGeneratedPositionsFor=function(k){var u=f.getArg(k,"line"),d={source:f.getArg(k,"source"),originalLine:u,originalColumn:f.getArg(k,"column",0)};null!=this.sourceRoot&&(d.source=f.relative(this.sourceRoot,d.source));if(!this._sources.has(d.source))return[];d.source=this._sources.indexOf(d.source);var g=[];d=this._findMapping(d,this._originalMappings,"originalLine",
"originalColumn",f.compareByOriginalPositions,c.LEAST_UPPER_BOUND);if(0<=d){var n=this._originalMappings[d];if(void 0===k.column)for(u=n.originalLine;n&&n.originalLine===u;)g.push({line:f.getArg(n,"generatedLine",null),column:f.getArg(n,"generatedColumn",null),lastColumn:f.getArg(n,"lastGeneratedColumn",null)}),n=this._originalMappings[++d];else for(k=n.originalColumn;n&&n.originalLine===u&&n.originalColumn==k;)g.push({line:f.getArg(n,"generatedLine",null),column:f.getArg(n,"generatedColumn",null),
lastColumn:f.getArg(n,"lastGeneratedColumn",null)}),n=this._originalMappings[++d]}return g};A.SourceMapConsumer=e;p.prototype=Object.create(e.prototype);p.prototype.consumer=e;p.fromSourceMap=function(k,u){var d=Object.create(p.prototype),g=d._names=l.fromArray(k._names.toArray(),!0),n=d._sources=l.fromArray(k._sources.toArray(),!0);d.sourceRoot=k._sourceRoot;d.sourcesContent=k._generateSourcesContent(d._sources.toArray(),d.sourceRoot);d.file=k._file;d._sourceMapURL=u;for(var v=k._mappings.toArray().slice(),
z=d.__generatedMappings=[],G=d.__originalMappings=[],D=0,L=v.length;D<L;D++){var a=v[D],b=new t;b.generatedLine=a.generatedLine;b.generatedColumn=a.generatedColumn;a.source&&(b.source=n.indexOf(a.source),b.originalLine=a.originalLine,b.originalColumn=a.originalColumn,a.name&&(b.name=g.indexOf(a.name)),G.push(b));z.push(b)}r(d.__originalMappings,f.compareByOriginalPositions);return d};p.prototype._version=3;Object.defineProperty(p.prototype,"sources",{get:function(){return this._sources.toArray().map(function(k){return f.computeSourceURL(this.sourceRoot,
k,this._sourceMapURL)},this)}});p.prototype._parseMappings=function(k,u){for(var d=1,g=0,n=0,v=0,z=0,G=0,D=k.length,L=0,a={},b={},h=[],w=[],y,I,K,N,P;L<D;)if(";"===k.charAt(L))d++,L++,g=0;else if(","===k.charAt(L))L++;else{y=new t;y.generatedLine=d;for(N=L;N<D&&!this._charIsMappingSeparator(k,N);N++);I=k.slice(L,N);if(K=a[I])L+=I.length;else{for(K=[];L<N;)q.decode(k,L,b),P=b.value,L=b.rest,K.push(P);if(2===K.length)throw Error("Found a source, but no line and column");if(3===K.length)throw Error("Found a source and line, but no column");
a[I]=K}y.generatedColumn=g+K[0];g=y.generatedColumn;1<K.length&&(y.source=z+K[1],z+=K[1],y.originalLine=n+K[2],n=y.originalLine,y.originalLine+=1,y.originalColumn=v+K[3],v=y.originalColumn,4<K.length&&(y.name=G+K[4],G+=K[4]));w.push(y);"number"===typeof y.originalLine&&h.push(y)}r(w,f.compareByGeneratedPositionsDeflated);this.__generatedMappings=w;r(h,f.compareByOriginalPositions);this.__originalMappings=h};p.prototype._findMapping=function(k,u,d,g,n,v){if(0>=k[d])throw new TypeError("Line must be greater than or equal to 1, got "+
k[d]);if(0>k[g])throw new TypeError("Column must be greater than or equal to 0, got "+k[g]);return c.search(k,u,n,v)};p.prototype.computeColumnSpans=function(){for(var k=0;k<this._generatedMappings.length;++k){var u=this._generatedMappings[k];if(k+1<this._generatedMappings.length){var d=this._generatedMappings[k+1];if(u.generatedLine===d.generatedLine){u.lastGeneratedColumn=d.generatedColumn-1;continue}}u.lastGeneratedColumn=Infinity}};p.prototype.originalPositionFor=function(k){var u={generatedLine:f.getArg(k,
"line"),generatedColumn:f.getArg(k,"column")};k=this._findMapping(u,this._generatedMappings,"generatedLine","generatedColumn",f.compareByGeneratedPositionsDeflated,f.getArg(k,"bias",e.GREATEST_LOWER_BOUND));if(0<=k&&(k=this._generatedMappings[k],k.generatedLine===u.generatedLine)){u=f.getArg(k,"source",null);null!==u&&(u=this._sources.at(u),u=f.computeSourceURL(this.sourceRoot,u,this._sourceMapURL));var d=f.getArg(k,"name",null);null!==d&&(d=this._names.at(d));return{source:u,line:f.getArg(k,"originalLine",
null),column:f.getArg(k,"originalColumn",null),name:d}}return{source:null,line:null,column:null,name:null}};p.prototype.hasContentsOfAllSources=function(){return this.sourcesContent?this.sourcesContent.length>=this._sources.size()&&!this.sourcesContent.some(function(k){return null==k}):!1};p.prototype.sourceContentFor=function(k,u){if(!this.sourcesContent)return null;var d=k;null!=this.sourceRoot&&(d=f.relative(this.sourceRoot,d));if(this._sources.has(d))return this.sourcesContent[this._sources.indexOf(d)];
var g=this.sources,n;for(n=0;n<g.length;++n)if(g[n]==k)return this.sourcesContent[n];var v;if(null!=this.sourceRoot&&(v=f.urlParse(this.sourceRoot))){g=d.replace(/^file:\/\//,"");if("file"==v.scheme&&this._sources.has(g))return this.sourcesContent[this._sources.indexOf(g)];if((!v.path||"/"==v.path)&&this._sources.has("/"+d))return this.sourcesContent[this._sources.indexOf("/"+d)]}if(u)return null;throw Error('"'+d+'" is not in the SourceMap.');};p.prototype.generatedPositionFor=function(k){var u=
f.getArg(k,"source");null!=this.sourceRoot&&(u=f.relative(this.sourceRoot,u));if(!this._sources.has(u))return{line:null,column:null,lastColumn:null};u=this._sources.indexOf(u);u={source:u,originalLine:f.getArg(k,"line"),originalColumn:f.getArg(k,"column")};k=this._findMapping(u,this._originalMappings,"originalLine","originalColumn",f.compareByOriginalPositions,f.getArg(k,"bias",e.GREATEST_LOWER_BOUND));return 0<=k&&(k=this._originalMappings[k],k.source===u.source)?{line:f.getArg(k,"generatedLine",
null),column:f.getArg(k,"generatedColumn",null),lastColumn:f.getArg(k,"lastGeneratedColumn",null)}:{line:null,column:null,lastColumn:null}};A.BasicSourceMapConsumer=p;m.prototype=Object.create(e.prototype);m.prototype.constructor=e;m.prototype._version=3;Object.defineProperty(m.prototype,"sources",{get:function(){for(var k=[],u=0;u<this._sections.length;u++)for(var d=0;d<this._sections[u].consumer.sources.length;d++)k.push(this._sections[u].consumer.sources[d]);return k}});m.prototype.originalPositionFor=
function(k){var u={generatedLine:f.getArg(k,"line"),generatedColumn:f.getArg(k,"column")},d=c.search(u,this._sections,function(g,n){var v=g.generatedLine-n.generatedOffset.generatedLine;return v?v:g.generatedColumn-n.generatedOffset.generatedColumn});return(d=this._sections[d])?d.consumer.originalPositionFor({line:u.generatedLine-(d.generatedOffset.generatedLine-1),column:u.generatedColumn-(d.generatedOffset.generatedLine===u.generatedLine?d.generatedOffset.generatedColumn-1:0),bias:k.bias}):{source:null,
line:null,column:null,name:null}};m.prototype.hasContentsOfAllSources=function(){return this._sections.every(function(k){return k.consumer.hasContentsOfAllSources()})};m.prototype.sourceContentFor=function(k,u){for(var d=0;d<this._sections.length;d++){var g=this._sections[d].consumer.sourceContentFor(k,!0);if(g)return g}if(u)return null;throw Error('"'+k+'" is not in the SourceMap.');};m.prototype.generatedPositionFor=function(k){for(var u=0;u<this._sections.length;u++){var d=this._sections[u];if(-1!==
d.consumer.sources.indexOf(f.getArg(k,"source"))){var g=d.consumer.generatedPositionFor(k);if(g)return{line:g.line+(d.generatedOffset.generatedLine-1),column:g.column+(d.generatedOffset.generatedLine===g.line?d.generatedOffset.generatedColumn-1:0)}}}return{line:null,column:null}};m.prototype._parseMappings=function(k,u){this.__generatedMappings=[];this.__originalMappings=[];for(var d=0;d<this._sections.length;d++)for(var g=this._sections[d],n=g.consumer._generatedMappings,v=0;v<n.length;v++){var z=
n[v],G=g.consumer._sources.at(z.source);G=f.computeSourceURL(g.consumer.sourceRoot,G,this._sourceMapURL);this._sources.add(G);G=this._sources.indexOf(G);var D=null;z.name&&(D=g.consumer._names.at(z.name),this._names.add(D),D=this._names.indexOf(D));z={source:G,generatedLine:z.generatedLine+(g.generatedOffset.generatedLine-1),generatedColumn:z.generatedColumn+(g.generatedOffset.generatedLine===z.generatedLine?g.generatedOffset.generatedColumn-1:0),originalLine:z.originalLine,originalColumn:z.originalColumn,
name:D};this.__generatedMappings.push(z);"number"===typeof z.originalLine&&this.__originalMappings.push(z)}r(this.__generatedMappings,f.compareByGeneratedPositionsDeflated);r(this.__originalMappings,f.compareByOriginalPositions)};A.IndexedSourceMapConsumer=m},{"./array-set":10,"./base64-vlq":11,"./binary-search":13,"./quick-sort":15,"./util":19}],17:[function(C,J,A){function e(c){c||(c={});this._file=t.getArg(c,"file",null);this._sourceRoot=t.getArg(c,"sourceRoot",null);this._skipValidation=t.getArg(c,
"skipValidation",!1);this._sources=new m;this._names=new m;this._mappings=new f;this._sourcesContents=null}var p=C("./base64-vlq"),t=C("./util"),m=C("./array-set").ArraySet,f=C("./mapping-list").MappingList;e.prototype._version=3;e.fromSourceMap=function(c){var l=c.sourceRoot,q=new e({file:c.file,sourceRoot:l});c.eachMapping(function(r){var k={generated:{line:r.generatedLine,column:r.generatedColumn}};null!=r.source&&(k.source=r.source,null!=l&&(k.source=t.relative(l,k.source)),k.original={line:r.originalLine,
column:r.originalColumn},null!=r.name&&(k.name=r.name));q.addMapping(k)});c.sources.forEach(function(r){var k=r;null!==l&&(k=t.relative(l,r));q._sources.has(k)||q._sources.add(k);k=c.sourceContentFor(r);null!=k&&q.setSourceContent(r,k)});return q};e.prototype.addMapping=function(c){var l=t.getArg(c,"generated"),q=t.getArg(c,"original",null),r=t.getArg(c,"source",null);c=t.getArg(c,"name",null);this._skipValidation||this._validateMapping(l,q,r,c);null!=r&&(r=String(r),this._sources.has(r)||this._sources.add(r));
null!=c&&(c=String(c),this._names.has(c)||this._names.add(c));this._mappings.add({generatedLine:l.line,generatedColumn:l.column,originalLine:null!=q&&q.line,originalColumn:null!=q&&q.column,source:r,name:c})};e.prototype.setSourceContent=function(c,l){var q=c;null!=this._sourceRoot&&(q=t.relative(this._sourceRoot,q));null!=l?(this._sourcesContents||(this._sourcesContents=Object.create(null)),this._sourcesContents[t.toSetString(q)]=l):this._sourcesContents&&(delete this._sourcesContents[t.toSetString(q)],
0===Object.keys(this._sourcesContents).length&&(this._sourcesContents=null))};e.prototype.applySourceMap=function(c,l,q){var r=l;if(null==l){if(null==c.file)throw Error('SourceMapGenerator.prototype.applySourceMap requires either an explicit source file, or the source map\'s "file" property. Both were omitted.');r=c.file}var k=this._sourceRoot;null!=k&&(r=t.relative(k,r));var u=new m,d=new m;this._mappings.unsortedForEach(function(g){if(g.source===r&&null!=g.originalLine){var n=c.originalPositionFor({line:g.originalLine,
column:g.originalColumn});null!=n.source&&(g.source=n.source,null!=q&&(g.source=t.join(q,g.source)),null!=k&&(g.source=t.relative(k,g.source)),g.originalLine=n.line,g.originalColumn=n.column,null!=n.name&&(g.name=n.name))}n=g.source;null==n||u.has(n)||u.add(n);g=g.name;null==g||d.has(g)||d.add(g)},this);this._sources=u;this._names=d;c.sources.forEach(function(g){var n=c.sourceContentFor(g);null!=n&&(null!=q&&(g=t.join(q,g)),null!=k&&(g=t.relative(k,g)),this.setSourceContent(g,n))},this)};e.prototype._validateMapping=
function(c,l,q,r){if(l&&"number"!==typeof l.line&&"number"!==typeof l.column)throw Error("original.line and original.column are not numbers -- you probably meant to omit the original mapping entirely and only map the generated position. If so, pass null for the original mapping instead of an object with empty or null values.");if(!(c&&"line"in c&&"column"in c&&0<c.line&&0<=c.column&&!l&&!q&&!r||c&&"line"in c&&"column"in c&&l&&"line"in l&&"column"in l&&0<c.line&&0<=c.column&&0<l.line&&0<=l.column&&
q))throw Error("Invalid mapping: "+JSON.stringify({generated:c,source:q,original:l,name:r}));};e.prototype._serializeMappings=function(){for(var c=0,l=1,q=0,r=0,k=0,u=0,d="",g,n,v,z=this._mappings.toArray(),G=0,D=z.length;G<D;G++){n=z[G];g="";if(n.generatedLine!==l)for(c=0;n.generatedLine!==l;)g+=";",l++;else if(0<G){if(!t.compareByGeneratedPositionsInflated(n,z[G-1]))continue;g+=","}g+=p.encode(n.generatedColumn-c);c=n.generatedColumn;null!=n.source&&(v=this._sources.indexOf(n.source),g+=p.encode(v-
u),u=v,g+=p.encode(n.originalLine-1-r),r=n.originalLine-1,g+=p.encode(n.originalColumn-q),q=n.originalColumn,null!=n.name&&(n=this._names.indexOf(n.name),g+=p.encode(n-k),k=n));d+=g}return d};e.prototype._generateSourcesContent=function(c,l){return c.map(function(q){if(!this._sourcesContents)return null;null!=l&&(q=t.relative(l,q));q=t.toSetString(q);return Object.prototype.hasOwnProperty.call(this._sourcesContents,q)?this._sourcesContents[q]:null},this)};e.prototype.toJSON=function(){var c={version:this._version,
sources:this._sources.toArray(),names:this._names.toArray(),mappings:this._serializeMappings()};null!=this._file&&(c.file=this._file);null!=this._sourceRoot&&(c.sourceRoot=this._sourceRoot);this._sourcesContents&&(c.sourcesContent=this._generateSourcesContent(c.sources,c.sourceRoot));return c};e.prototype.toString=function(){return JSON.stringify(this.toJSON())};A.SourceMapGenerator=e},{"./array-set":10,"./base64-vlq":11,"./mapping-list":14,"./util":19}],18:[function(C,J,A){function e(f,c,l,q,r){this.children=
[];this.sourceContents={};this.line=null==f?null:f;this.column=null==c?null:c;this.source=null==l?null:l;this.name=null==r?null:r;this.$$$isSourceNode$$$=!0;null!=q&&this.add(q)}var p=C("./source-map-generator").SourceMapGenerator,t=C("./util"),m=/(\r?\n)/;e.fromStringWithSourceMap=function(f,c,l){function q(z,G){if(null===z||void 0===z.source)r.add(G);else{var D=l?t.join(l,z.source):z.source;r.add(new e(z.originalLine,z.originalColumn,D,G,z.name))}}var r=new e,k=f.split(m),u=0,d=function(){var z=
u<k.length?k[u++]:void 0,G=(u<k.length?k[u++]:void 0)||"";return z+G},g=1,n=0,v=null;c.eachMapping(function(z){if(null!==v)if(g<z.generatedLine)q(v,d()),g++,n=0;else{var G=k[u]||"",D=G.substr(0,z.generatedColumn-n);k[u]=G.substr(z.generatedColumn-n);n=z.generatedColumn;q(v,D);v=z;return}for(;g<z.generatedLine;)r.add(d()),g++;n<z.generatedColumn&&(G=k[u]||"",r.add(G.substr(0,z.generatedColumn)),k[u]=G.substr(z.generatedColumn),n=z.generatedColumn);v=z},this);u<k.length&&(v&&q(v,d()),r.add(k.splice(u).join("")));
c.sources.forEach(function(z){var G=c.sourceContentFor(z);null!=G&&(null!=l&&(z=t.join(l,z)),r.setSourceContent(z,G))});return r};e.prototype.add=function(f){if(Array.isArray(f))f.forEach(function(c){this.add(c)},this);else if(f.$$$isSourceNode$$$||"string"===typeof f)f&&this.children.push(f);else throw new TypeError("Expected a SourceNode, string, or an array of SourceNodes and strings. Got "+f);return this};e.prototype.prepend=function(f){if(Array.isArray(f))for(var c=f.length-1;0<=c;c--)this.prepend(f[c]);
else if(f.$$$isSourceNode$$$||"string"===typeof f)this.children.unshift(f);else throw new TypeError("Expected a SourceNode, string, or an array of SourceNodes and strings. Got "+f);return this};e.prototype.walk=function(f){for(var c,l=0,q=this.children.length;l<q;l++)c=this.children[l],c.$$$isSourceNode$$$?c.walk(f):""!==c&&f(c,{source:this.source,line:this.line,column:this.column,name:this.name})};e.prototype.join=function(f){var c,l=this.children.length;if(0<l){var q=[];for(c=0;c<l-1;c++)q.push(this.children[c]),
q.push(f);q.push(this.children[c]);this.children=q}return this};e.prototype.replaceRight=function(f,c){var l=this.children[this.children.length-1];l.$$$isSourceNode$$$?l.replaceRight(f,c):"string"===typeof l?this.children[this.children.length-1]=l.replace(f,c):this.children.push("".replace(f,c));return this};e.prototype.setSourceContent=function(f,c){this.sourceContents[t.toSetString(f)]=c};e.prototype.walkSourceContents=function(f){for(var c=0,l=this.children.length;c<l;c++)this.children[c].$$$isSourceNode$$$&&
this.children[c].walkSourceContents(f);var q=Object.keys(this.sourceContents);c=0;for(l=q.length;c<l;c++)f(t.fromSetString(q[c]),this.sourceContents[q[c]])};e.prototype.toString=function(){var f="";this.walk(function(c){f+=c});return f};e.prototype.toStringWithSourceMap=function(f){var c="",l=1,q=0,r=new p(f),k=!1,u=null,d=null,g=null,n=null;this.walk(function(v,z){c+=v;null!==z.source&&null!==z.line&&null!==z.column?(u===z.source&&d===z.line&&g===z.column&&n===z.name||r.addMapping({source:z.source,
original:{line:z.line,column:z.column},generated:{line:l,column:q},name:z.name}),u=z.source,d=z.line,g=z.column,n=z.name,k=!0):k&&(r.addMapping({generated:{line:l,column:q}}),u=null,k=!1);for(var G=0,D=v.length;G<D;G++)10===v.charCodeAt(G)?(l++,q=0,G+1===D?(u=null,k=!1):k&&r.addMapping({source:z.source,original:{line:z.line,column:z.column},generated:{line:l,column:q},name:z.name})):q++});this.walkSourceContents(function(v,z){r.setSourceContent(v,z)});return{code:c,map:r}};A.SourceNode=e},{"./source-map-generator":17,
"./util":19}],19:[function(C,J,A){function e(d){return(d=d.match(k))?{scheme:d[1],auth:d[2],host:d[3],port:d[4],path:d[5]}:null}function p(d){var g="";d.scheme&&(g+=d.scheme+":");g+="//";d.auth&&(g+=d.auth+"@");d.host&&(g+=d.host);d.port&&(g+=":"+d.port);d.path&&(g+=d.path);return g}function t(d){var g=d,n=e(d);if(n){if(!n.path)return d;g=n.path}d=A.isAbsolute(g);g=g.split(/\/+/);for(var v,z=0,G=g.length-1;0<=G;G--)v=g[G],"."===v?g.splice(G,1):".."===v?z++:0<z&&(""===v?(g.splice(G+1,z),z=0):(g.splice(G,
2),z--));g=g.join("/");""===g&&(g=d?"/":".");return n?(n.path=g,p(n)):g}function m(d,g){""===d&&(d=".");""===g&&(g=".");var n=e(g),v=e(d);v&&(d=v.path||"/");if(n&&!n.scheme)return v&&(n.scheme=v.scheme),p(n);if(n||g.match(u))return g;if(v&&!v.host&&!v.path)return v.host=g,p(v);n="/"===g.charAt(0)?g:t(d.replace(/\/+$/,"")+"/"+g);return v?(v.path=n,p(v)):n}function f(d){return d}function c(d){return q(d)?"$"+d:d}function l(d){return q(d)?d.slice(1):d}function q(d){if(!d)return!1;var g=d.length;if(9>
g||95!==d.charCodeAt(g-1)||95!==d.charCodeAt(g-2)||111!==d.charCodeAt(g-3)||116!==d.charCodeAt(g-4)||111!==d.charCodeAt(g-5)||114!==d.charCodeAt(g-6)||112!==d.charCodeAt(g-7)||95!==d.charCodeAt(g-8)||95!==d.charCodeAt(g-9))return!1;for(g-=10;0<=g;g--)if(36!==d.charCodeAt(g))return!1;return!0}function r(d,g){return d===g?0:null===d?1:null===g?-1:d>g?1:-1}A.getArg=function(d,g,n){if(g in d)return d[g];if(3===arguments.length)return n;throw Error('"'+g+'" is a required argument.');};var k=/^(?:([\w+\-.]+):)?\/\/(?:(\w+:\w+)@)?([\w.-]*)(?::(\d+))?(.*)$/,
u=/^data:.+,.+$/;A.urlParse=e;A.urlGenerate=p;A.normalize=t;A.join=m;A.isAbsolute=function(d){return"/"===d.charAt(0)||k.test(d)};A.relative=function(d,g){""===d&&(d=".");d=d.replace(/\/$/,"");for(var n=0;0!==g.indexOf(d+"/");){var v=d.lastIndexOf("/");if(0>v)return g;d=d.slice(0,v);if(d.match(/^([^\/]+:\/)?\/*$/))return g;++n}return Array(n+1).join("../")+g.substr(d.length+1)};C=!("__proto__"in Object.create(null));A.toSetString=C?f:c;A.fromSetString=C?f:l;A.compareByOriginalPositions=function(d,
g,n){var v=r(d.source,g.source);if(0!==v)return v;v=d.originalLine-g.originalLine;if(0!==v)return v;v=d.originalColumn-g.originalColumn;if(0!==v||n)return v;v=d.generatedColumn-g.generatedColumn;if(0!==v)return v;v=d.generatedLine-g.generatedLine;return 0!==v?v:r(d.name,g.name)};A.compareByGeneratedPositionsDeflated=function(d,g,n){var v=d.generatedLine-g.generatedLine;if(0!==v)return v;v=d.generatedColumn-g.generatedColumn;if(0!==v||n)return v;v=r(d.source,g.source);if(0!==v)return v;v=d.originalLine-
g.originalLine;if(0!==v)return v;v=d.originalColumn-g.originalColumn;return 0!==v?v:r(d.name,g.name)};A.compareByGeneratedPositionsInflated=function(d,g){var n=d.generatedLine-g.generatedLine;if(0!==n)return n;n=d.generatedColumn-g.generatedColumn;if(0!==n)return n;n=r(d.source,g.source);if(0!==n)return n;n=d.originalLine-g.originalLine;if(0!==n)return n;n=d.originalColumn-g.originalColumn;return 0!==n?n:r(d.name,g.name)};A.parseSourceMapInput=function(d){return JSON.parse(d.replace(/^\)]}'[^\n]*\n/,
""))};A.computeSourceURL=function(d,g,n){g=g||"";d&&("/"!==d[d.length-1]&&"/"!==g[0]&&(d+="/"),g=d+g);if(n){d=e(n);if(!d)throw Error("sourceMapURL could not be parsed");d.path&&(n=d.path.lastIndexOf("/"),0<=n&&(d.path=d.path.substring(0,n+1)));g=m(p(d),g)}return t(g)}},{}],20:[function(C,J,A){A.SourceMapGenerator=C("./lib/source-map-generator").SourceMapGenerator;A.SourceMapConsumer=C("./lib/source-map-consumer").SourceMapConsumer;A.SourceNode=C("./lib/source-node").SourceNode},{"./lib/source-map-consumer":16,
"./lib/source-map-generator":17,"./lib/source-node":18}],21:[function(C,J,A){(function(e){function p(){return"browser"===a?!0:"node"===a?!1:"undefined"!==typeof window&&"function"===typeof XMLHttpRequest&&!(window.require&&window.module&&window.process&&"renderer"===window.process.type)}function t(x){return function(B){for(var F=0;F<x.length;F++){var E=x[F](B);if(E)return E}return null}}function m(x,B){if(!x)return B;var F=n.dirname(x),E=/^\w+:\/\/[^\/]*/.exec(F);E=E?E[0]:"";var H=F.slice(E.length);
return E&&/^\/\w:/.test(H)?(E+="/",E+n.resolve(F.slice(E.length),B).replace(/\\/g,"/")):E+n.resolve(F.slice(E.length),B)}function f(x){var B=h[x.source];if(!B){var F=N(x.source);F?(B=h[x.source]={url:F.url,map:new g(F.map)},B.map.sourcesContent&&B.map.sources.forEach(function(E,H){var M=B.map.sourcesContent[H];if(M){var S=m(B.url,E);b[S]=M}})):B=h[x.source]={url:null,map:null}}return B&&B.map&&"function"===typeof B.map.originalPositionFor&&(F=B.map.originalPositionFor(x),null!==F.source)?(F.source=
m(B.url,F.source),F):x}function c(x){var B=/^eval at ([^(]+) \((.+):(\d+):(\d+)\)$/.exec(x);return B?(x=f({source:B[2],line:+B[3],column:B[4]-1}),"eval at "+B[1]+" ("+x.source+":"+x.line+":"+(x.column+1)+")"):(B=/^eval at ([^(]+) \((.+)\)$/.exec(x))?"eval at "+B[1]+" ("+c(B[2])+")":x}function l(){var x="";if(this.isNative())x="native";else{var B=this.getScriptNameOrSourceURL();!B&&this.isEval()&&(x=this.getEvalOrigin(),x+=", ");x=B?x+B:x+"<anonymous>";B=this.getLineNumber();null!=B&&(x+=":"+B,(B=
this.getColumnNumber())&&(x+=":"+B))}B="";var F=this.getFunctionName(),E=!0,H=this.isConstructor();if(this.isToplevel()||H)H?B+="new "+(F||"<anonymous>"):F?B+=F:(B+=x,E=!1);else{H=this.getTypeName();"[object Object]"===H&&(H="null");var M=this.getMethodName();F?(H&&0!=F.indexOf(H)&&(B+=H+"."),B+=F,M&&F.indexOf("."+M)!=F.length-M.length-1&&(B+=" [as "+M+"]")):B+=H+"."+(M||"<anonymous>")}E&&(B+=" ("+x+")");return B}function q(x){var B={};Object.getOwnPropertyNames(Object.getPrototypeOf(x)).forEach(function(F){B[F]=
/^(?:is|get)/.test(F)?function(){return x[F].call(x)}:x[F]});B.toString=l;return B}function r(x,B){void 0===B&&(B={nextPosition:null,curPosition:null});if(x.isNative())return B.curPosition=null,x;var F=x.getFileName()||x.getScriptNameOrSourceURL();if(F){var E=x.getLineNumber(),H=x.getColumnNumber()-1,M=/^v(10\.1[6-9]|10\.[2-9][0-9]|10\.[0-9]{3,}|1[2-9]\d*|[2-9]\d|\d{3,}|11\.11)/,S=M.test;var V="object"===typeof e&&null!==e?e.version:"";M=S.call(M,V)?0:62;1===E&&H>M&&!p()&&!x.isEval()&&(H-=M);var O=
f({source:F,line:E,column:H});B.curPosition=O;x=q(x);var T=x.getFunctionName;x.getFunctionName=function(){return null==B.nextPosition?T():B.nextPosition.name||T()};x.getFileName=function(){return O.source};x.getLineNumber=function(){return O.line};x.getColumnNumber=function(){return O.column+1};x.getScriptNameOrSourceURL=function(){return O.source};return x}var Q=x.isEval()&&x.getEvalOrigin();Q&&(Q=c(Q),x=q(x),x.getEvalOrigin=function(){return Q});return x}function k(x,B){L&&(b={},h={});for(var F=
(x.name||"Error")+": "+(x.message||""),E={nextPosition:null,curPosition:null},H=[],M=B.length-1;0<=M;M--)H.push("\n at "+r(B[M],E)),E.nextPosition=E.curPosition;E.curPosition=E.nextPosition=null;return F+H.reverse().join("")}function u(x){var B=/\n at [^(]+ \((.*):(\d+):(\d+)\)/.exec(x.stack);if(B){x=B[1];var F=+B[2];B=+B[3];var E=b[x];if(!E&&v&&v.existsSync(x))try{E=v.readFileSync(x,"utf8")}catch(H){E=""}if(E&&(E=E.split(/(?:\r\n|\r|\n)/)[F-1]))return x+":"+F+"\n"+E+"\n"+Array(B).join(" ")+
"^"}return null}function d(){var x=e.emit;e.emit=function(B){if("uncaughtException"===B){var F=arguments[1]&&arguments[1].stack,E=0<this.listeners(B).length;if(F&&!E){F=arguments[1];E=u(F);var H="object"===typeof e&&null!==e?e.stderr:void 0;H&&H._handle&&H._handle.setBlocking&&H._handle.setBlocking(!0);E&&(console.error(),console.error(E));console.error(F.stack);"object"===typeof e&&null!==e&&"function"===typeof e.exit&&e.exit(1);return}}return x.apply(this,arguments)}}var g=C("source-map").SourceMapConsumer,
n=C("path");try{var v=C("fs");v.existsSync&&v.readFileSync||(v=null)}catch(x){}var z=C("buffer-from"),G=!1,D=!1,L=!1,a="auto",b={},h={},w=/^data:application\/json[^,]+base64,/,y=[],I=[],K=t(y);y.push(function(x){x=x.trim();/^file:/.test(x)&&(x=x.replace(/file:\/\/\/(\w:)?/,function(E,H){return H?"":"/"}));if(x in b)return b[x];var B="";try{if(v)v.existsSync(x)&&(B=v.readFileSync(x,"utf8"));else{var F=new XMLHttpRequest;F.open("GET",x,!1);F.send(null);4===F.readyState&&200===F.status&&(B=F.responseText)}}catch(E){}return b[x]=
B});var N=t(I);I.push(function(x){a:{if(p())try{var B=new XMLHttpRequest;B.open("GET",x,!1);B.send(null);var F=B.getResponseHeader("SourceMap")||B.getResponseHeader("X-SourceMap");if(F){var E=F;break a}}catch(M){}E=K(x);B=/(?:\/\/[@#][\s]*sourceMappingURL=([^\s'"]+)[\s]*$)|(?:\/\*[@#][\s]*sourceMappingURL=([^\s*'"]+)[\s]*(?:\*\/)[\s]*$)/mg;for(var H;F=B.exec(E);)H=F;E=H?H[1]:null}if(!E)return null;w.test(E)?(H=E.slice(E.indexOf(",")+1),H=z(H,"base64").toString(),E=x):(E=m(x,E),H=K(E));return H?{url:E,
map:H}:null});var P=y.slice(0),W=I.slice(0);A.wrapCallSite=r;A.getErrorSource=u;A.mapSourcePosition=f;A.retrieveSourceMap=N;A.install=function(x){x=x||{};if(x.environment&&(a=x.environment,-1===["node","browser","auto"].indexOf(a)))throw Error("environment "+a+" was unknown. Available options are {auto, browser, node}");x.retrieveFile&&(x.overrideRetrieveFile&&(y.length=0),y.unshift(x.retrieveFile));x.retrieveSourceMap&&(x.overrideRetrieveSourceMap&&(I.length=0),I.unshift(x.retrieveSourceMap));if(x.hookRequire&&
!p()){var B=J.require("module"),F=B.prototype._compile;F.__sourceMapSupport||(B.prototype._compile=function(E,H){b[H]=E;h[H]=void 0;return F.call(this,E,H)},B.prototype._compile.__sourceMapSupport=!0)}L||(L="emptyCacheBetweenOperations"in x?x.emptyCacheBetweenOperations:!1);G||(G=!0,Error.prepareStackTrace=k);if(!D){x="handleUncaughtExceptions"in x?x.handleUncaughtExceptions:!0;try{!1===J.require("worker_threads").isMainThread&&(x=!1)}catch(E){}x&&"object"===typeof e&&null!==e&&"function"===typeof e.on&&
(D=!0,d())}};A.resetRetrieveHandlers=function(){y.length=0;I.length=0;y=P.slice(0);I=W.slice(0);N=t(I);K=t(y)}}).call(this,C("g5I+bs"))},{"buffer-from":4,fs:3,"g5I+bs":9,path:8,"source-map":20}]},{},[1]);return R});

View File

@ -0,0 +1,50 @@
{
"name": "@cspotcode/source-map-support",
"description": "Fixes stack traces for files with source maps",
"version": "0.8.1",
"main": "./source-map-support.js",
"types": "./source-map-support.d.ts",
"scripts": {
"build": "node build.js",
"serve-tests": "http-server -p 1336",
"test": "mocha"
},
"files": [
"/register.d.ts",
"/register.js",
"/register-hook-require.d.ts",
"/register-hook-require.js",
"/source-map-support.d.ts",
"/source-map-support.js",
"/browser-source-map-support.js"
],
"dependencies": {
"@jridgewell/trace-mapping": "0.3.9"
},
"devDependencies": {
"@types/lodash": "^4.14.182",
"browserify": "^4.2.3",
"coffeescript": "^1.12.7",
"http-server": "^0.11.1",
"lodash": "^4.17.21",
"mocha": "^3.5.3",
"semver": "^7.3.7",
"source-map": "0.6.1",
"webpack": "^1.15.0"
},
"repository": {
"type": "git",
"url": "https://github.com/cspotcode/node-source-map-support"
},
"bugs": {
"url": "https://github.com/cspotcode/node-source-map-support/issues"
},
"license": "MIT",
"engines": {
"node": ">=12"
},
"volta": {
"node": "16.11.0",
"npm": "7.24.2"
}
}

View File

@ -0,0 +1,7 @@
// tslint:disable:no-useless-files
// For following usage:
// import '@cspotcode/source-map-support/register-hook-require'
// Instead of:
// import sourceMapSupport from '@cspotcode/source-map-support'
// sourceMapSupport.install({hookRequire: true})

View File

@ -0,0 +1,3 @@
require('./').install({
hookRequire: true
});

View File

@ -0,0 +1,7 @@
// tslint:disable:no-useless-files
// For following usage:
// import '@cspotcode/source-map-support/register'
// Instead of:
// import sourceMapSupport from '@cspotcode/source-map-support'
// sourceMapSupport.install()

View File

@ -0,0 +1 @@
require('./').install();

View File

@ -0,0 +1,76 @@
// Type definitions for source-map-support 0.5
// Project: https://github.com/evanw/node-source-map-support
// Definitions by: Bart van der Schoor <https://github.com/Bartvds>
// Jason Cheatham <https://github.com/jason0x43>
// Alcedo Nathaniel De Guzman Jr <https://github.com/natealcedo>
// Griffin Yourick <https://github.com/tough-griff>
// Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped
export interface RawSourceMap {
version: 3;
sources: string[];
names: string[];
sourceRoot?: string;
sourcesContent?: string[];
mappings: string;
file: string;
}
/**
* Output of retrieveSourceMap().
* From source-map-support:
* The map field may be either a string or the parsed JSON object (i.e.,
* it must be a valid argument to the SourceMapConsumer constructor).
*/
export interface UrlAndMap {
url: string;
map: string | RawSourceMap;
}
/**
* Options to install().
*/
export interface Options {
handleUncaughtExceptions?: boolean | undefined;
hookRequire?: boolean | undefined;
emptyCacheBetweenOperations?: boolean | undefined;
environment?: 'auto' | 'browser' | 'node' | undefined;
overrideRetrieveFile?: boolean | undefined;
overrideRetrieveSourceMap?: boolean | undefined;
retrieveFile?(path: string): string;
retrieveSourceMap?(source: string): UrlAndMap | null;
/**
* Set false to disable redirection of require / import `source-map-support` to `@cspotcode/source-map-support`
*/
redirectConflictingLibrary?: boolean;
/**
* Callback will be called every time we redirect due to `redirectConflictingLibrary`
* This allows consumers to log helpful warnings if they choose.
* @param parent NodeJS.Module which made the require() or require.resolve() call
* @param options options object internally passed to node's `_resolveFilename` hook
*/
onConflictingLibraryRedirect?: (request: string, parent: any, isMain: boolean, options: any, redirectedRequest: string) => void;
}
export interface Position {
source: string;
line: number;
column: number;
}
export function wrapCallSite(frame: any /* StackFrame */): any /* StackFrame */;
export function getErrorSource(error: Error): string | null;
export function mapSourcePosition(position: Position): Position;
export function retrieveSourceMap(source: string): UrlAndMap | null;
export function resetRetrieveHandlers(): void;
/**
* Install SourceMap support.
* @param options Can be used to e.g. disable uncaughtException handler.
*/
export function install(options?: Options): void;
/**
* Uninstall SourceMap support.
*/
export function uninstall(): void;

View File

@ -0,0 +1,938 @@
const { TraceMap, originalPositionFor, AnyMap } = require('@jridgewell/trace-mapping');
var path = require('path');
const { fileURLToPath, pathToFileURL } = require('url');
var util = require('util');
var fs;
try {
fs = require('fs');
if (!fs.existsSync || !fs.readFileSync) {
// fs doesn't have all methods we need
fs = null;
}
} catch (err) {
/* nop */
}
/**
* Requires a module which is protected against bundler minification.
*
* @param {NodeModule} mod
* @param {string} request
*/
function dynamicRequire(mod, request) {
return mod.require(request);
}
/**
* @typedef {{
* enabled: boolean;
* originalValue: any;
* installedValue: any;
* }} HookState
* Used for installing and uninstalling hooks
*/
// Increment this if the format of sharedData changes in a breaking way.
var sharedDataVersion = 1;
/**
* @template T
* @param {T} defaults
* @returns {T}
*/
function initializeSharedData(defaults) {
var sharedDataKey = 'source-map-support/sharedData';
if (typeof Symbol !== 'undefined') {
sharedDataKey = Symbol.for(sharedDataKey);
}
var sharedData = this[sharedDataKey];
if (!sharedData) {
sharedData = { version: sharedDataVersion };
if (Object.defineProperty) {
Object.defineProperty(this, sharedDataKey, { value: sharedData });
} else {
this[sharedDataKey] = sharedData;
}
}
if (sharedDataVersion !== sharedData.version) {
throw new Error("Multiple incompatible instances of source-map-support were loaded");
}
for (var key in defaults) {
if (!(key in sharedData)) {
sharedData[key] = defaults[key];
}
}
return sharedData;
}
// If multiple instances of source-map-support are loaded into the same
// context, they shouldn't overwrite each other. By storing handlers, caches,
// and other state on a shared object, different instances of
// source-map-support can work together in a limited way. This does require
// that future versions of source-map-support continue to support the fields on
// this object. If this internal contract ever needs to be broken, increment
// sharedDataVersion. (This version number is not the same as any of the
// package's version numbers, which should reflect the *external* API of
// source-map-support.)
var sharedData = initializeSharedData({
// Only install once if called multiple times
// Remember how the environment looked before installation so we can restore if able
/** @type {HookState} */
errorPrepareStackTraceHook: undefined,
/** @type {HookState} */
processEmitHook: undefined,
/** @type {HookState} */
moduleResolveFilenameHook: undefined,
/** @type {Array<(request: string, parent: any, isMain: boolean, options: any, redirectedRequest: string) => void>} */
onConflictingLibraryRedirectArr: [],
// If true, the caches are reset before a stack trace formatting operation
emptyCacheBetweenOperations: false,
// Maps a file path to a string containing the file contents
fileContentsCache: Object.create(null),
// Maps a file path to a source map for that file
/** @type {Record<string, {url: string, map: TraceMap}} */
sourceMapCache: Object.create(null),
// Priority list of retrieve handlers
retrieveFileHandlers: [],
retrieveMapHandlers: [],
// Priority list of internally-implemented handlers.
// When resetting state, we must keep these.
internalRetrieveFileHandlers: [],
internalRetrieveMapHandlers: [],
});
// Supports {browser, node, auto}
var environment = "auto";
// Regex for detecting source maps
var reSourceMap = /^data:application\/json[^,]+base64,/;
function isInBrowser() {
if (environment === "browser")
return true;
if (environment === "node")
return false;
return ((typeof window !== 'undefined') && (typeof XMLHttpRequest === 'function') && !(window.require && window.module && window.process && window.process.type === "renderer"));
}
function hasGlobalProcessEventEmitter() {
return ((typeof process === 'object') && (process !== null) && (typeof process.on === 'function'));
}
function tryFileURLToPath(v) {
if(isFileUrl(v)) {
return fileURLToPath(v);
}
return v;
}
// TODO un-copy these from resolve-uri; see if they can be exported from that lib
function isFileUrl(input) {
return input.startsWith('file:');
}
function isAbsoluteUrl(input) {
return schemeRegex.test(input);
}
// Matches the scheme of a URL, eg "http://"
const schemeRegex = /^[\w+.-]+:\/\//;
function isSchemeRelativeUrl(input) {
return input.startsWith('//');
}
// #region Caches
/** @param {string} pathOrFileUrl */
function getCacheKey(pathOrFileUrl) {
if(pathOrFileUrl.startsWith('node:')) return pathOrFileUrl;
if(isFileUrl(pathOrFileUrl)) {
// Must normalize spaces to %20, stuff like that
return new URL(pathOrFileUrl).toString();
} else {
try {
return pathToFileURL(pathOrFileUrl).toString();
} catch {
return pathOrFileUrl;
}
}
}
function getFileContentsCache(key) {
return sharedData.fileContentsCache[getCacheKey(key)];
}
function hasFileContentsCacheFromKey(key) {
return Object.prototype.hasOwnProperty.call(sharedData.fileContentsCache, key);
}
function getFileContentsCacheFromKey(key) {
return sharedData.fileContentsCache[key];
}
function setFileContentsCache(key, value) {
return sharedData.fileContentsCache[getCacheKey(key)] = value;
}
function getSourceMapCache(key) {
return sharedData.sourceMapCache[getCacheKey(key)];
}
function setSourceMapCache(key, value) {
return sharedData.sourceMapCache[getCacheKey(key)] = value;
}
function clearCaches() {
sharedData.fileContentsCache = Object.create(null);
sharedData.sourceMapCache = Object.create(null);
}
// #endregion Caches
function handlerExec(list, internalList) {
return function(arg) {
for (var i = 0; i < list.length; i++) {
var ret = list[i](arg);
if (ret) {
return ret;
}
}
for (var i = 0; i < internalList.length; i++) {
var ret = internalList[i](arg);
if (ret) {
return ret;
}
}
return null;
};
}
var retrieveFile = handlerExec(sharedData.retrieveFileHandlers, sharedData.internalRetrieveFileHandlers);
sharedData.internalRetrieveFileHandlers.push(function(path) {
// Trim the path to make sure there is no extra whitespace.
path = path.trim();
if (/^file:/.test(path)) {
// existsSync/readFileSync can't handle file protocol, but once stripped, it works
path = path.replace(/file:\/\/\/(\w:)?/, function(protocol, drive) {
return drive ?
'' : // file:///C:/dir/file -> C:/dir/file
'/'; // file:///root-dir/file -> /root-dir/file
});
}
const key = getCacheKey(path);
if(hasFileContentsCacheFromKey(key)) {
return getFileContentsCacheFromKey(key);
}
var contents = '';
try {
if (!fs) {
// Use SJAX if we are in the browser
var xhr = new XMLHttpRequest();
xhr.open('GET', path, /** async */ false);
xhr.send(null);
if (xhr.readyState === 4 && xhr.status === 200) {
contents = xhr.responseText;
}
} else if (fs.existsSync(path)) {
// Otherwise, use the filesystem
contents = fs.readFileSync(path, 'utf8');
}
} catch (er) {
/* ignore any errors */
}
return setFileContentsCache(path, contents);
});
// Support URLs relative to a directory, but be careful about a protocol prefix
// in case we are in the browser (i.e. directories may start with "http://" or "file:///")
function supportRelativeURL(file, url) {
if(!file) return url;
// given that this happens within error formatting codepath, probably best to
// fallback instead of throwing if anything goes wrong
try {
// if should output a URL
if(isAbsoluteUrl(file) || isSchemeRelativeUrl(file)) {
if(isAbsoluteUrl(url) || isSchemeRelativeUrl(url)) {
return new URL(url, file).toString();
}
if(path.isAbsolute(url)) {
return new URL(pathToFileURL(url), file).toString();
}
// url is relative path or URL
return new URL(url.replace(/\\/g, '/'), file).toString();
}
// if should output a path (unless URL is something like https://)
if(path.isAbsolute(file)) {
if(isFileUrl(url)) {
return fileURLToPath(url);
}
if(isSchemeRelativeUrl(url)) {
return fileURLToPath(new URL(url, 'file://'));
}
if(isAbsoluteUrl(url)) {
// url is a non-file URL
// Go with the URL
return url;
}
if(path.isAbsolute(url)) {
// Normalize at all? decodeURI or normalize slashes?
return path.normalize(url);
}
// url is relative path or URL
return path.join(file, '..', decodeURI(url));
}
// If we get here, file is relative.
// Shouldn't happen since node identifies modules with absolute paths or URLs.
// But we can take a stab at returning something meaningful anyway.
if(isAbsoluteUrl(url) || isSchemeRelativeUrl(url)) {
return url;
}
return path.join(file, '..', url);
} catch(e) {
return url;
}
}
// Return pathOrUrl in the same style as matchStyleOf: either a file URL or a native path
function matchStyleOfPathOrUrl(matchStyleOf, pathOrUrl) {
try {
if(isAbsoluteUrl(matchStyleOf) || isSchemeRelativeUrl(matchStyleOf)) {
if(isAbsoluteUrl(pathOrUrl) || isSchemeRelativeUrl(pathOrUrl)) return pathOrUrl;
if(path.isAbsolute(pathOrUrl)) return pathToFileURL(pathOrUrl).toString();
} else if(path.isAbsolute(matchStyleOf)) {
if(isAbsoluteUrl(pathOrUrl) || isSchemeRelativeUrl(pathOrUrl)) {
return fileURLToPath(new URL(pathOrUrl, 'file://'));
}
}
return pathOrUrl;
} catch(e) {
return pathOrUrl;
}
}
function retrieveSourceMapURL(source) {
var fileData;
if (isInBrowser()) {
try {
var xhr = new XMLHttpRequest();
xhr.open('GET', source, false);
xhr.send(null);
fileData = xhr.readyState === 4 ? xhr.responseText : null;
// Support providing a sourceMappingURL via the SourceMap header
var sourceMapHeader = xhr.getResponseHeader("SourceMap") ||
xhr.getResponseHeader("X-SourceMap");
if (sourceMapHeader) {
return sourceMapHeader;
}
} catch (e) {
}
}
// Get the URL of the source map
fileData = retrieveFile(tryFileURLToPath(source));
var re = /(?:\/\/[@#][\s]*sourceMappingURL=([^\s'"]+)[\s]*$)|(?:\/\*[@#][\s]*sourceMappingURL=([^\s*'"]+)[\s]*(?:\*\/)[\s]*$)/mg;
// Keep executing the search to find the *last* sourceMappingURL to avoid
// picking up sourceMappingURLs from comments, strings, etc.
var lastMatch, match;
while (match = re.exec(fileData)) lastMatch = match;
if (!lastMatch) return null;
return lastMatch[1];
};
// Can be overridden by the retrieveSourceMap option to install. Takes a
// generated source filename; returns a {map, optional url} object, or null if
// there is no source map. The map field may be either a string or the parsed
// JSON object (ie, it must be a valid argument to the SourceMapConsumer
// constructor).
/** @type {(source: string) => import('./source-map-support').UrlAndMap | null} */
var retrieveSourceMap = handlerExec(sharedData.retrieveMapHandlers, sharedData.internalRetrieveMapHandlers);
sharedData.internalRetrieveMapHandlers.push(function(source) {
var sourceMappingURL = retrieveSourceMapURL(source);
if (!sourceMappingURL) return null;
// Read the contents of the source map
var sourceMapData;
if (reSourceMap.test(sourceMappingURL)) {
// Support source map URL as a data url
var rawData = sourceMappingURL.slice(sourceMappingURL.indexOf(',') + 1);
sourceMapData = Buffer.from(rawData, "base64").toString();
sourceMappingURL = source;
} else {
// Support source map URLs relative to the source URL
sourceMappingURL = supportRelativeURL(source, sourceMappingURL);
sourceMapData = retrieveFile(tryFileURLToPath(sourceMappingURL));
}
if (!sourceMapData) {
return null;
}
return {
url: sourceMappingURL,
map: sourceMapData
};
});
function mapSourcePosition(position) {
var sourceMap = getSourceMapCache(position.source);
if (!sourceMap) {
// Call the (overrideable) retrieveSourceMap function to get the source map.
var urlAndMap = retrieveSourceMap(position.source);
if (urlAndMap) {
sourceMap = setSourceMapCache(position.source, {
url: urlAndMap.url,
map: new AnyMap(urlAndMap.map, urlAndMap.url)
});
// Overwrite trace-mapping's resolutions, because they do not handle
// Windows paths the way we want.
// TODO Remove now that windows path support was added to resolve-uri and thus trace-mapping?
sourceMap.map.resolvedSources = sourceMap.map.sources.map(s => supportRelativeURL(sourceMap.url, s));
// Load all sources stored inline with the source map into the file cache
// to pretend like they are already loaded. They may not exist on disk.
if (sourceMap.map.sourcesContent) {
sourceMap.map.resolvedSources.forEach(function(resolvedSource, i) {
var contents = sourceMap.map.sourcesContent[i];
if (contents) {
setFileContentsCache(resolvedSource, contents);
}
});
}
} else {
sourceMap = setSourceMapCache(position.source, {
url: null,
map: null
});
}
}
// Resolve the source URL relative to the URL of the source map
if (sourceMap && sourceMap.map) {
var originalPosition = originalPositionFor(sourceMap.map, position);
// Only return the original position if a matching line was found. If no
// matching line is found then we return position instead, which will cause
// the stack trace to print the path and line for the compiled file. It is
// better to give a precise location in the compiled file than a vague
// location in the original file.
if (originalPosition.source !== null) {
// originalPosition.source has *already* been resolved against sourceMap.url
// so is *already* as absolute as possible.
// However, we want to ensure we output in same format as input: URL or native path
originalPosition.source = matchStyleOfPathOrUrl(
position.source, originalPosition.source);
return originalPosition;
}
}
return position;
}
// Parses code generated by FormatEvalOrigin(), a function inside V8:
// https://code.google.com/p/v8/source/browse/trunk/src/messages.js
function mapEvalOrigin(origin) {
// Most eval() calls are in this format
var match = /^eval at ([^(]+) \((.+):(\d+):(\d+)\)$/.exec(origin);
if (match) {
var position = mapSourcePosition({
source: match[2],
line: +match[3],
column: match[4] - 1
});
return 'eval at ' + match[1] + ' (' + position.source + ':' +
position.line + ':' + (position.column + 1) + ')';
}
// Parse nested eval() calls using recursion
match = /^eval at ([^(]+) \((.+)\)$/.exec(origin);
if (match) {
return 'eval at ' + match[1] + ' (' + mapEvalOrigin(match[2]) + ')';
}
// Make sure we still return useful information if we didn't find anything
return origin;
}
// This is copied almost verbatim from the V8 source code at
// https://code.google.com/p/v8/source/browse/trunk/src/messages.js
// Update 2022-04-29:
// https://github.com/v8/v8/blob/98f6f100c5ab8e390e51422747c4ef644d5ac6f2/src/builtins/builtins-callsite.cc#L175-L179
// https://github.com/v8/v8/blob/98f6f100c5ab8e390e51422747c4ef644d5ac6f2/src/objects/call-site-info.cc#L795-L804
// https://github.com/v8/v8/blob/98f6f100c5ab8e390e51422747c4ef644d5ac6f2/src/objects/call-site-info.cc#L717-L750
// The implementation of wrapCallSite() used to just forward to the actual source
// code of CallSite.prototype.toString but unfortunately a new release of V8
// did something to the prototype chain and broke the shim. The only fix I
// could find was copy/paste.
function CallSiteToString() {
var fileName;
var fileLocation = "";
if (this.isNative()) {
fileLocation = "native";
} else {
fileName = this.getScriptNameOrSourceURL();
if (!fileName && this.isEval()) {
fileLocation = this.getEvalOrigin();
fileLocation += ", "; // Expecting source position to follow.
}
if (fileName) {
fileLocation += fileName;
} else {
// Source code does not originate from a file and is not native, but we
// can still get the source position inside the source string, e.g. in
// an eval string.
fileLocation += "<anonymous>";
}
var lineNumber = this.getLineNumber();
if (lineNumber != null) {
fileLocation += ":" + lineNumber;
var columnNumber = this.getColumnNumber();
if (columnNumber) {
fileLocation += ":" + columnNumber;
}
}
}
var line = "";
var isAsync = this.isAsync ? this.isAsync() : false;
if(isAsync) {
line += 'async ';
var isPromiseAll = this.isPromiseAll ? this.isPromiseAll() : false;
var isPromiseAny = this.isPromiseAny ? this.isPromiseAny() : false;
if(isPromiseAny || isPromiseAll) {
line += isPromiseAll ? 'Promise.all (index ' : 'Promise.any (index ';
var promiseIndex = this.getPromiseIndex();
line += promiseIndex + ')';
}
}
var functionName = this.getFunctionName();
var addSuffix = true;
var isConstructor = this.isConstructor();
var isMethodCall = !(this.isToplevel() || isConstructor);
if (isMethodCall) {
var typeName = this.getTypeName();
// Fixes shim to be backward compatable with Node v0 to v4
if (typeName === "[object Object]") {
typeName = "null";
}
var methodName = this.getMethodName();
if (functionName) {
if (typeName && functionName.indexOf(typeName) != 0) {
line += typeName + ".";
}
line += functionName;
if (methodName && functionName.indexOf("." + methodName) != functionName.length - methodName.length - 1) {
line += " [as " + methodName + "]";
}
} else {
line += typeName + "." + (methodName || "<anonymous>");
}
} else if (isConstructor) {
line += "new " + (functionName || "<anonymous>");
} else if (functionName) {
line += functionName;
} else {
line += fileLocation;
addSuffix = false;
}
if (addSuffix) {
line += " (" + fileLocation + ")";
}
return line;
}
function cloneCallSite(frame) {
var object = {};
Object.getOwnPropertyNames(Object.getPrototypeOf(frame)).forEach(function(name) {
object[name] = /^(?:is|get)/.test(name) ? function() { return frame[name].call(frame); } : frame[name];
});
object.toString = CallSiteToString;
return object;
}
function wrapCallSite(frame, state) {
// provides interface backward compatibility
if (state === undefined) {
state = { nextPosition: null, curPosition: null }
}
if(frame.isNative()) {
state.curPosition = null;
return frame;
}
// Most call sites will return the source file from getFileName(), but code
// passed to eval() ending in "//# sourceURL=..." will return the source file
// from getScriptNameOrSourceURL() instead
var source = frame.getFileName() || frame.getScriptNameOrSourceURL();
if (source) {
// v8 does not expose its internal isWasm, etc methods, so we do this instead.
if(source.startsWith('wasm://')) {
state.curPosition = null;
return frame;
}
var line = frame.getLineNumber();
var column = frame.getColumnNumber() - 1;
// Fix position in Node where some (internal) code is prepended.
// See https://github.com/evanw/node-source-map-support/issues/36
// Header removed in node at ^10.16 || >=11.11.0
// v11 is not an LTS candidate, we can just test the one version with it.
// Test node versions for: 10.16-19, 10.20+, 12-19, 20-99, 100+, or 11.11
var noHeader = /^v(10\.1[6-9]|10\.[2-9][0-9]|10\.[0-9]{3,}|1[2-9]\d*|[2-9]\d|\d{3,}|11\.11)/;
var headerLength = noHeader.test(process.version) ? 0 : 62;
if (line === 1 && column > headerLength && !isInBrowser() && !frame.isEval()) {
column -= headerLength;
}
var position = mapSourcePosition({
source: source,
line: line,
column: column
});
state.curPosition = position;
frame = cloneCallSite(frame);
var originalFunctionName = frame.getFunctionName;
frame.getFunctionName = function() {
if (state.nextPosition == null) {
return originalFunctionName();
}
return state.nextPosition.name || originalFunctionName();
};
frame.getFileName = function() { return position.source; };
frame.getLineNumber = function() { return position.line; };
frame.getColumnNumber = function() { return position.column + 1; };
frame.getScriptNameOrSourceURL = function() { return position.source; };
return frame;
}
// Code called using eval() needs special handling
var origin = frame.isEval() && frame.getEvalOrigin();
if (origin) {
origin = mapEvalOrigin(origin);
frame = cloneCallSite(frame);
frame.getEvalOrigin = function() { return origin; };
return frame;
}
// If we get here then we were unable to change the source position
return frame;
}
var kIsNodeError = undefined;
try {
// Get a deliberate ERR_INVALID_ARG_TYPE
// TODO is there a better way to reliably get an instance of NodeError?
path.resolve(123);
} catch(e) {
const symbols = Object.getOwnPropertySymbols(e);
const symbol = symbols.find(function (s) {return s.toString().indexOf('kIsNodeError') >= 0});
if(symbol) kIsNodeError = symbol;
}
const ErrorPrototypeToString = (err) =>Error.prototype.toString.call(err);
/** @param {HookState} hookState */
function createPrepareStackTrace(hookState) {
return prepareStackTrace;
// This function is part of the V8 stack trace API, for more info see:
// https://v8.dev/docs/stack-trace-api
function prepareStackTrace(error, stack) {
if(!hookState.enabled) return hookState.originalValue.apply(this, arguments);
if (sharedData.emptyCacheBetweenOperations) {
clearCaches();
}
// node gives its own errors special treatment. Mimic that behavior
// https://github.com/nodejs/node/blob/3cbaabc4622df1b4009b9d026a1a970bdbae6e89/lib/internal/errors.js#L118-L128
// https://github.com/nodejs/node/pull/39182
var errorString;
if (kIsNodeError) {
if(kIsNodeError in error) {
errorString = `${error.name} [${error.code}]: ${error.message}`;
} else {
errorString = ErrorPrototypeToString(error);
}
} else {
var name = error.name || 'Error';
var message = error.message || '';
errorString = message ? name + ": " + message : name;
}
var state = { nextPosition: null, curPosition: null };
var processedStack = [];
for (var i = stack.length - 1; i >= 0; i--) {
processedStack.push('\n at ' + wrapCallSite(stack[i], state));
state.nextPosition = state.curPosition;
}
state.curPosition = state.nextPosition = null;
return errorString + processedStack.reverse().join('');
}
}
// Generate position and snippet of original source with pointer
function getErrorSource(error) {
var match = /\n at [^(]+ \((.*):(\d+):(\d+)\)/.exec(error.stack);
if (match) {
var source = match[1];
var line = +match[2];
var column = +match[3];
// Support the inline sourceContents inside the source map
var contents = getFileContentsCache(source);
const sourceAsPath = tryFileURLToPath(source);
// Support files on disk
if (!contents && fs && fs.existsSync(sourceAsPath)) {
try {
contents = fs.readFileSync(sourceAsPath, 'utf8');
} catch (er) {
contents = '';
}
}
// Format the line from the original source code like node does
if (contents) {
var code = contents.split(/(?:\r\n|\r|\n)/)[line - 1];
if (code) {
return source + ':' + line + '\n' + code + '\n' +
new Array(column).join(' ') + '^';
}
}
}
return null;
}
function printFatalErrorUponExit (error) {
var source = getErrorSource(error);
// Ensure error is printed synchronously and not truncated
if (process.stderr._handle && process.stderr._handle.setBlocking) {
process.stderr._handle.setBlocking(true);
}
if (source) {
console.error(source);
}
// Matches node's behavior for colorized output
console.error(
util.inspect(error, {
customInspect: false,
colors: process.stderr.isTTY
})
);
}
function shimEmitUncaughtException () {
const originalValue = process.emit;
var hook = sharedData.processEmitHook = {
enabled: true,
originalValue,
installedValue: undefined
};
var isTerminatingDueToFatalException = false;
var fatalException;
process.emit = sharedData.processEmitHook.installedValue = function (type) {
const hadListeners = originalValue.apply(this, arguments);
if(hook.enabled) {
if (type === 'uncaughtException' && !hadListeners) {
isTerminatingDueToFatalException = true;
fatalException = arguments[1];
process.exit(1);
}
if (type === 'exit' && isTerminatingDueToFatalException) {
printFatalErrorUponExit(fatalException);
}
}
return hadListeners;
};
}
var originalRetrieveFileHandlers = sharedData.retrieveFileHandlers.slice(0);
var originalRetrieveMapHandlers = sharedData.retrieveMapHandlers.slice(0);
exports.wrapCallSite = wrapCallSite;
exports.getErrorSource = getErrorSource;
exports.mapSourcePosition = mapSourcePosition;
exports.retrieveSourceMap = retrieveSourceMap;
exports.install = function(options) {
options = options || {};
if (options.environment) {
environment = options.environment;
if (["node", "browser", "auto"].indexOf(environment) === -1) {
throw new Error("environment " + environment + " was unknown. Available options are {auto, browser, node}")
}
}
// Use dynamicRequire to avoid including in browser bundles
var Module = dynamicRequire(module, 'module');
// Redirect subsequent imports of "source-map-support"
// to this package
const {redirectConflictingLibrary = true, onConflictingLibraryRedirect} = options;
if(redirectConflictingLibrary) {
if (!sharedData.moduleResolveFilenameHook) {
const originalValue = Module._resolveFilename;
const moduleResolveFilenameHook = sharedData.moduleResolveFilenameHook = {
enabled: true,
originalValue,
installedValue: undefined,
}
Module._resolveFilename = sharedData.moduleResolveFilenameHook.installedValue = function (request, parent, isMain, options) {
if (moduleResolveFilenameHook.enabled) {
// Match all source-map-support entrypoints: source-map-support, source-map-support/register
let requestRedirect;
if (request === 'source-map-support') {
requestRedirect = './';
} else if (request === 'source-map-support/register') {
requestRedirect = './register';
}
if (requestRedirect !== undefined) {
const newRequest = require.resolve(requestRedirect);
for (const cb of sharedData.onConflictingLibraryRedirectArr) {
cb(request, parent, isMain, options, newRequest);
}
request = newRequest;
}
}
return originalValue.call(this, request, parent, isMain, options);
}
}
if (onConflictingLibraryRedirect) {
sharedData.onConflictingLibraryRedirectArr.push(onConflictingLibraryRedirect);
}
}
// Allow sources to be found by methods other than reading the files
// directly from disk.
if (options.retrieveFile) {
if (options.overrideRetrieveFile) {
sharedData.retrieveFileHandlers.length = 0;
}
sharedData.retrieveFileHandlers.unshift(options.retrieveFile);
}
// Allow source maps to be found by methods other than reading the files
// directly from disk.
if (options.retrieveSourceMap) {
if (options.overrideRetrieveSourceMap) {
sharedData.retrieveMapHandlers.length = 0;
}
sharedData.retrieveMapHandlers.unshift(options.retrieveSourceMap);
}
// Support runtime transpilers that include inline source maps
if (options.hookRequire && !isInBrowser()) {
var $compile = Module.prototype._compile;
if (!$compile.__sourceMapSupport) {
Module.prototype._compile = function(content, filename) {
setFileContentsCache(filename, content);
setSourceMapCache(filename, undefined);
return $compile.call(this, content, filename);
};
Module.prototype._compile.__sourceMapSupport = true;
}
}
// Configure options
if (!sharedData.emptyCacheBetweenOperations) {
sharedData.emptyCacheBetweenOperations = 'emptyCacheBetweenOperations' in options ?
options.emptyCacheBetweenOperations : false;
}
// Install the error reformatter
if (!sharedData.errorPrepareStackTraceHook) {
const originalValue = Error.prepareStackTrace;
sharedData.errorPrepareStackTraceHook = {
enabled: true,
originalValue,
installedValue: undefined
};
Error.prepareStackTrace = sharedData.errorPrepareStackTraceHook.installedValue = createPrepareStackTrace(sharedData.errorPrepareStackTraceHook);
}
if (!sharedData.processEmitHook) {
var installHandler = 'handleUncaughtExceptions' in options ?
options.handleUncaughtExceptions : true;
// Do not override 'uncaughtException' with our own handler in Node.js
// Worker threads. Workers pass the error to the main thread as an event,
// rather than printing something to stderr and exiting.
try {
// We need to use `dynamicRequire` because `require` on it's own will be optimized by WebPack/Browserify.
var worker_threads = dynamicRequire(module, 'worker_threads');
if (worker_threads.isMainThread === false) {
installHandler = false;
}
} catch(e) {}
// Provide the option to not install the uncaught exception handler. This is
// to support other uncaught exception handlers (in test frameworks, for
// example). If this handler is not installed and there are no other uncaught
// exception handlers, uncaught exceptions will be caught by node's built-in
// exception handler and the process will still be terminated. However, the
// generated JavaScript code will be shown above the stack trace instead of
// the original source code.
if (installHandler && hasGlobalProcessEventEmitter()) {
shimEmitUncaughtException();
}
}
};
exports.uninstall = function() {
if(sharedData.processEmitHook) {
// Disable behavior
sharedData.processEmitHook.enabled = false;
// If possible, remove our hook function. May not be possible if subsequent third-party hooks have wrapped around us.
if(process.emit === sharedData.processEmitHook.installedValue) {
process.emit = sharedData.processEmitHook.originalValue;
}
sharedData.processEmitHook = undefined;
}
if(sharedData.errorPrepareStackTraceHook) {
// Disable behavior
sharedData.errorPrepareStackTraceHook.enabled = false;
// If possible or necessary, remove our hook function.
// In vanilla environments, prepareStackTrace is `undefined`.
// We cannot delegate to `undefined` the way we can to a function w/`.apply()`; our only option is to remove the function.
// If we are the *first* hook installed, and another was installed on top of us, we have no choice but to remove both.
if(Error.prepareStackTrace === sharedData.errorPrepareStackTraceHook.installedValue || typeof sharedData.errorPrepareStackTraceHook.originalValue !== 'function') {
Error.prepareStackTrace = sharedData.errorPrepareStackTraceHook.originalValue;
}
sharedData.errorPrepareStackTraceHook = undefined;
}
if (sharedData.moduleResolveFilenameHook) {
// Disable behavior
sharedData.moduleResolveFilenameHook.enabled = false;
// If possible, remove our hook function. May not be possible if subsequent third-party hooks have wrapped around us.
var Module = dynamicRequire(module, 'module');
if(Module._resolveFilename === sharedData.moduleResolveFilenameHook.installedValue) {
Module._resolveFilename = sharedData.moduleResolveFilenameHook.originalValue;
}
sharedData.moduleResolveFilenameHook = undefined;
}
sharedData.onConflictingLibraryRedirectArr.length = 0;
}
exports.resetRetrieveHandlers = function() {
sharedData.retrieveFileHandlers.length = 0;
sharedData.retrieveMapHandlers.length = 0;
}

View File

@ -0,0 +1 @@
../../../@jridgewell+trace-mapping@0.3.9/node_modules/@jridgewell/trace-mapping

View File

@ -0,0 +1,3 @@
# esbuild
This is the Linux 64-bit binary for esbuild, a JavaScript bundler and minifier. See https://github.com/evanw/esbuild for details.

Binary file not shown.

View File

@ -0,0 +1,20 @@
{
"name": "@esbuild/linux-x64",
"version": "0.25.9",
"description": "The Linux 64-bit binary for esbuild, a JavaScript bundler.",
"repository": {
"type": "git",
"url": "git+https://github.com/evanw/esbuild.git"
},
"license": "MIT",
"preferUnplugged": true,
"engines": {
"node": ">=18"
},
"os": [
"linux"
],
"cpu": [
"x64"
]
}

View File

@ -0,0 +1,202 @@
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "[]"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright [yyyy] [name of copyright owner]
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

View File

@ -0,0 +1,377 @@
# Google Gen AI SDK for TypeScript and JavaScript
[![NPM Downloads](https://img.shields.io/npm/dw/%40google%2Fgenai)](https://www.npmjs.com/package/@google/genai)
[![Node Current](https://img.shields.io/node/v/%40google%2Fgenai)](https://www.npmjs.com/package/@google/genai)
----------------------
**Documentation:** https://googleapis.github.io/js-genai/
----------------------
The Google Gen AI JavaScript SDK is designed for
TypeScript and JavaScript developers to build applications powered by Gemini. The SDK
supports both the [Gemini Developer API](https://ai.google.dev/gemini-api/docs)
and [Vertex AI](https://cloud.google.com/vertex-ai/generative-ai/docs/learn/overview).
The Google Gen AI SDK is designed to work with Gemini 2.0 features.
> [!CAUTION]
> **API Key Security:** Avoid exposing API keys in client-side code.
> Use server-side implementations in production environments.
## Prerequisites
1. Node.js version 20 or later
### The following are required for Vertex AI users (excluding Vertex AI Studio)
1. [Select](https://console.cloud.google.com/project) or [create](https://cloud.google.com/resource-manager/docs/creating-managing-projects#creating_a_project) a Google Cloud project.
1. [Enable billing for your project](https://cloud.google.com/billing/docs/how-to/modify-project).
1. [Enable the Vertex AI API](https://console.cloud.google.com/flows/enableapi?apiid=aiplatform.googleapis.com).
1. [Configure authentication](https://cloud.google.com/docs/authentication) for your project.
* [Install the gcloud CLI](https://cloud.google.com/sdk/docs/install).
* [Initialize the gcloud CLI](https://cloud.google.com/sdk/docs/initializing).
* Create local authentication credentials for your user account:
```sh
gcloud auth application-default login
```
A list of accepted authentication options are listed in [GoogleAuthOptions](https://github.com/googleapis/google-auth-library-nodejs/blob/3ae120d0a45c95e36c59c9ac8286483938781f30/src/auth/googleauth.ts#L87) interface of google-auth-library-node.js GitHub repo.
## Installation
To install the SDK, run the following command:
```shell
npm install @google/genai
```
## Quickstart
The simplest way to get started is to use an API key from
[Google AI Studio](https://aistudio.google.com/apikey):
```typescript
import {GoogleGenAI} from '@google/genai';
const GEMINI_API_KEY = process.env.GEMINI_API_KEY;
const ai = new GoogleGenAI({apiKey: GEMINI_API_KEY});
async function main() {
const response = await ai.models.generateContent({
model: 'gemini-2.0-flash-001',
contents: 'Why is the sky blue?',
});
console.log(response.text);
}
main();
```
## Initialization
The Google Gen AI SDK provides support for both the
[Google AI Studio](https://ai.google.dev/gemini-api/docs) and
[Vertex AI](https://cloud.google.com/vertex-ai/generative-ai/docs/learn/overview)
implementations of the Gemini API.
### Gemini Developer API
For server-side applications, initialize using an API key, which can
be acquired from [Google AI Studio](https://aistudio.google.com/apikey):
```typescript
import { GoogleGenAI } from '@google/genai';
const ai = new GoogleGenAI({apiKey: 'GEMINI_API_KEY'});
```
#### Browser
> [!CAUTION]
> **API Key Security:** Avoid exposing API keys in client-side code.
> Use server-side implementations in production environments.
In the browser the initialization code is identical:
```typescript
import { GoogleGenAI } from '@google/genai';
const ai = new GoogleGenAI({apiKey: 'GEMINI_API_KEY'});
```
### Vertex AI
Sample code for VertexAI initialization:
```typescript
import { GoogleGenAI } from '@google/genai';
const ai = new GoogleGenAI({
vertexai: true,
project: 'your_project',
location: 'your_location',
});
```
### (Optional) (NodeJS only) Using environment variables:
For NodeJS environments, you can create a client by configuring the necessary
environment variables. Configuration setup instructions depends on whether
you're using the Gemini Developer API or the Gemini API in Vertex AI.
**Gemini Developer API:** Set `GOOGLE_API_KEY` as shown below:
```bash
export GOOGLE_API_KEY='your-api-key'
```
**Gemini API on Vertex AI:** Set `GOOGLE_GENAI_USE_VERTEXAI`,
`GOOGLE_CLOUD_PROJECT` and `GOOGLE_CLOUD_LOCATION`, as shown below:
```bash
export GOOGLE_GENAI_USE_VERTEXAI=true
export GOOGLE_CLOUD_PROJECT='your-project-id'
export GOOGLE_CLOUD_LOCATION='us-central1'
```
```typescript
import {GoogleGenAI} from '@google/genai';
const ai = new GoogleGenAI();
```
## API Selection
By default, the SDK uses the beta API endpoints provided by Google to support
preview features in the APIs. The stable API endpoints can be selected by
setting the API version to `v1`.
To set the API version use `apiVersion`. For example, to set the API version to
`v1` for Vertex AI:
```typescript
const ai = new GoogleGenAI({
vertexai: true,
project: 'your_project',
location: 'your_location',
apiVersion: 'v1'
});
```
To set the API version to `v1alpha` for the Gemini Developer API:
```typescript
const ai = new GoogleGenAI({
apiKey: 'GEMINI_API_KEY',
apiVersion: 'v1alpha'
});
```
## GoogleGenAI overview
All API features are accessed through an instance of the `GoogleGenAI` classes.
The submodules bundle together related API methods:
- [`ai.models`](https://googleapis.github.io/js-genai/release_docs/classes/models.Models.html):
Use `models` to query models (`generateContent`, `generateImages`, ...), or
examine their metadata.
- [`ai.caches`](https://googleapis.github.io/js-genai/release_docs/classes/caches.Caches.html):
Create and manage `caches` to reduce costs when repeatedly using the same
large prompt prefix.
- [`ai.chats`](https://googleapis.github.io/js-genai/release_docs/classes/chats.Chats.html):
Create local stateful `chat` objects to simplify multi turn interactions.
- [`ai.files`](https://googleapis.github.io/js-genai/release_docs/classes/files.Files.html):
Upload `files` to the API and reference them in your prompts.
This reduces bandwidth if you use a file many times, and handles files too
large to fit inline with your prompt.
- [`ai.live`](https://googleapis.github.io/js-genai/release_docs/classes/live.Live.html):
Start a `live` session for real time interaction, allows text + audio + video
input, and text or audio output.
## Samples
More samples can be found in the
[github samples directory](https://github.com/googleapis/js-genai/tree/main/sdk-samples).
### Streaming
For quicker, more responsive API interactions use the `generateContentStream`
method which yields chunks as they're generated:
```typescript
import {GoogleGenAI} from '@google/genai';
const GEMINI_API_KEY = process.env.GEMINI_API_KEY;
const ai = new GoogleGenAI({apiKey: GEMINI_API_KEY});
async function main() {
const response = await ai.models.generateContentStream({
model: 'gemini-2.0-flash-001',
contents: 'Write a 100-word poem.',
});
for await (const chunk of response) {
console.log(chunk.text);
}
}
main();
```
### Function Calling
To let Gemini to interact with external systems, you can provide
`functionDeclaration` objects as `tools`. To use these tools it's a 4 step
1. **Declare the function name, description, and parametersJsonSchema**
2. **Call `generateContent` with function calling enabled**
3. **Use the returned `FunctionCall` parameters to call your actual function**
3. **Send the result back to the model (with history, easier in `ai.chat`)
as a `FunctionResponse`**
```typescript
import {GoogleGenAI, FunctionCallingConfigMode, FunctionDeclaration, Type} from '@google/genai';
const GEMINI_API_KEY = process.env.GEMINI_API_KEY;
async function main() {
const controlLightDeclaration: FunctionDeclaration = {
name: 'controlLight',
parametersJsonSchema: {
type: 'object',
properties:{
brightness: {
type:'number',
},
colorTemperature: {
type:'string',
},
},
required: ['brightness', 'colorTemperature'],
},
};
const ai = new GoogleGenAI({apiKey: GEMINI_API_KEY});
const response = await ai.models.generateContent({
model: 'gemini-2.0-flash-001',
contents: 'Dim the lights so the room feels cozy and warm.',
config: {
toolConfig: {
functionCallingConfig: {
// Force it to call any function
mode: FunctionCallingConfigMode.ANY,
allowedFunctionNames: ['controlLight'],
}
},
tools: [{functionDeclarations: [controlLightDeclaration]}]
}
});
console.log(response.functionCalls);
}
main();
```
#### Model Context Protocol (MCP) support (experimental)
Built-in [MCP](https://modelcontextprotocol.io/introduction) support is an
experimental feature. You can pass a local MCP server as a tool directly.
```javascript
import { GoogleGenAI, FunctionCallingConfigMode , mcpToTool} from '@google/genai';
import { Client } from "@modelcontextprotocol/sdk/client/index.js";
import { StdioClientTransport } from "@modelcontextprotocol/sdk/client/stdio.js";
// Create server parameters for stdio connection
const serverParams = new StdioClientTransport({
command: "npx", // Executable
args: ["-y", "@philschmid/weather-mcp"] // MCP Server
});
const client = new Client(
{
name: "example-client",
version: "1.0.0"
}
);
// Configure the client
const ai = new GoogleGenAI({});
// Initialize the connection between client and server
await client.connect(serverParams);
// Send request to the model with MCP tools
const response = await ai.models.generateContent({
model: "gemini-2.5-flash",
contents: `What is the weather in London in ${new Date().toLocaleDateString()}?`,
config: {
tools: [mcpToTool(client)], // uses the session, will automatically call the tool using automatic function calling
},
});
console.log(response.text);
// Close the connection
await client.close();
```
### Generate Content
#### How to structure `contents` argument for `generateContent`
The SDK allows you to specify the following types in the `contents` parameter:
#### Content
- `Content`: The SDK will wrap the singular `Content` instance in an array which
contains only the given content instance
- `Content[]`: No transformation happens
#### Part
Parts will be aggregated on a singular Content, with role 'user'.
- `Part | string`: The SDK will wrap the `string` or `Part` in a `Content`
instance with role 'user'.
- `Part[] | string[]`: The SDK will wrap the full provided list into a single
`Content` with role 'user'.
**_NOTE:_** This doesn't apply to `FunctionCall` and `FunctionResponse` parts,
if you are specifying those, you need to explicitly provide the full
`Content[]` structure making it explicit which Parts are 'spoken' by the model,
or the user. The SDK will throw an exception if you try this.
## Error Handling
To handle errors raised by the API, the SDK provides this [ApiError](https://github.com/googleapis/js-genai/blob/main/src/errors.ts) class.
```typescript
import {GoogleGenAI} from '@google/genai';
const GEMINI_API_KEY = process.env.GEMINI_API_KEY;
const ai = new GoogleGenAI({apiKey: GEMINI_API_KEY});
async function main() {
await ai.models.generateContent({
model: 'non-existent-model',
contents: 'Write a 100-word poem.',
}).catch((e) => {
console.error('error name: ', e.name);
console.error('error message: ', e.message);
console.error('error status: ', e.status);
});
}
main();
```
## How is this different from the other Google AI SDKs
This SDK (`@google/genai`) is Google Deepminds "vanilla" SDK for its generative
AI offerings, and is where Google Deepmind adds new AI features.
Models hosted either on the [Vertex AI platform](https://cloud.google.com/vertex-ai/generative-ai/docs/learn/overview) or the [Gemini Developer platform](https://ai.google.dev/gemini-api/docs) are accessible through this SDK.
Other SDKs may be offering additional AI frameworks on top of this SDK, or may
be targeting specific project environments (like Firebase).
The `@google/generative_language` and `@google-cloud/vertexai` SDKs are previous
iterations of this SDK and are no longer receiving new Gemini 2.0+ features.

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,4 @@
{
"name": "@google/genai/node",
"main": "../dist/node/index.js"
}

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