diff --git a/.agents/DESIGN.md b/.agents/DESIGN.md
new file mode 100644
index 00000000..be8a5e71
--- /dev/null
+++ b/.agents/DESIGN.md
@@ -0,0 +1,95 @@
+# Design System Document: The Editorial Node
+
+## 1. Overview & Creative North Star
+
+This design system moves away from the "standard bootstrap" look of tech communities toward a high-end editorial experience.
+
+**Creative North Star: "The Editorial Node"**
+Our vision is to treat community information as curated content rather than a database. We bridge the gap between technical precision and human-centric connection. The aesthetic utilizes intentional asymmetry, generous whitespace (derived from our `Spacing Scale`), and a sophisticated layering of surfaces to create a sense of digital "physicality." We don't just list events; we showcase a movement.
+
+## 2. Colors & Surface Architecture
+
+The palette is rooted in the high-energy `#e84a5f`, supported by a nuanced spectrum of architectural neutrals.
+
+### The "No-Line" Rule
+
+**Explicit Instruction:** You are prohibited from using 1px solid borders for sectioning or containment.
+Boundaries must be defined solely through:
+
+- **Background Color Shifts:** A `surface-container-low` section sitting on a `surface` background.
+- **Tonal Transitions:** Using the `surface-container` tiers (Lowest to Highest) to define nesting.
+
+### Surface Hierarchy & Nesting
+
+Treat the UI as a series of stacked sheets of fine material.
+
+- **The Base:** Use `surface` (#f1fbff) for the primary background.
+- **The Section:** Use `surface-container-low` (#eaf5fa) for large content areas.
+- **The Detail:** Use `surface-container-highest` (#e84a5f) for interactive elements like input fields or active state cards.
+
+### The "Glass & Gradient" Rule
+
+To elevate the experience, floating elements (Modals, Navigation Bars, Hovering Tooltips) should utilize **Glassmorphism**.
+
+- **Backdrop Blur:** 12px to 20px.
+- **Fill:** A semi-transparent version of `surface` (e.g., 80% opacity).
+- **Signature Gradient:** For high-impact CTAs, use a subtle linear gradient from `primary` (#b11f3b) to `primary_container` (#d33b51) at a 135-degree angle. This adds "soul" to the technical interface.
+
+## 3. Typography
+
+The typography system balances the technical nature of developers with the premium feel of a lifestyle brand.
+
+- **Display & Headlines (Space Grotesk):** This typeface offers a "technical-humanist" feel. Its geometric traps and expressive terminals convey innovation. Use `display-lg` for hero statements with tight letter-spacing (-0.02em).
+- **Body & Titles (Inter):** Chosen for its exceptional legibility and neutral tone. It provides the "clean" developer-friendly feel requested.
+- **Technical Details:** Where code snippets or technical metadata (e.g., repo sizes, timestamps) appear, use a monospace font-family at `label-sm` scale to provide a subtle "hacker" nod.
+
+## 4. Elevation & Depth
+
+Depth is achieved through **Tonal Layering** rather than structural shadows.
+
+- **The Layering Principle:** Place a `surface-container-lowest` card on a `surface-container-low` section. This creates a soft, natural lift that feels like high-quality paper.
+- **Ambient Shadows:** If a floating effect is required (e.g., a "Join Us" button or a featured Event Card), use an extra-diffused shadow:
+- _Blur:_ 32px
+- _Spread:_ -4px
+- _Opacity:_ 6% of the `on_surface` color.
+- **The "Ghost Border" Fallback:** If accessibility demands a container edge, use a Ghost Border: `outline_variant` at **15% opacity**. Never 100%.
+
+## 5. Components
+
+### Buttons
+
+- **Primary:** High-polish gradient (`primary` to `primary_container`). Large padding (Scale 3 on sides, 2 on top/bottom). `Roundedness: md`.
+- **Secondary:** No fill. `Ghost Border` (15% opacity `outline`). `on_surface` text.
+- **Tertiary:** No fill, no border. Underline only on hover.
+
+### Community Group Cards
+
+Forbid the use of divider lines.
+
+- **Style:** A `surface-container-low` base that shifts to `surface-container-highest` on hover.
+- **Layout:** Use asymmetrical spacing—more padding at the top (Scale 6) than the bottom (Scale 4) to create an editorial "header" feel within the card.
+
+### Filtered Video Library & Chips
+
+- **Chips:** Use `secondary_container` with `on_secondary_container` text. When selected, use `primary` with `on_primary`.
+- **Video Cards:** Use a 16:9 aspect ratio for thumbnails. Overlay a glassmorphic "Play" button in the center. Metadata should use `body-sm` for the description and a monospace `label-sm` for the video duration.
+
+### Input Fields & Search
+
+- **Style:** Minimalist. No border. Use `surface-container-highest` as the fill.
+- **State:** On focus, the background remains, but a 2px `primary` underline animates from the center.
+
+## 6. Do’s and Don’ts
+
+### Do:
+
+- **Embrace Whitespace:** If you think there is enough space, add one more step from the `Spacing Scale`. Space is a luxury.
+- **Nesting Surfaces:** Use the `surface-container` tiers to guide the eye. The darker/more saturated the container, the more "nested" it should feel.
+- **Intentional Asymmetry:** Align text to the left but allow imagery or decorative branding elements to "break" the grid and bleed off-screen.
+
+### Don’t:
+
+- **No Hard Outlines:** Never use a 100% opaque border to separate a sidebar or a card. It breaks the editorial flow.
+- **No Pure Black:** Even in Dark Mode, use the `surface` and `on_surface` tokens. Pure #000000 kills the "premium" depth.
+- **No Standard Shadows:** Avoid the "fuzzy grey" shadow. If you must use a shadow, tint it with the primary or surface color to keep it integrated with the environment.
+- **No Over-Crowding:** Don't try to fit 5 event cards in a row. Use 2 or 3 to allow the brand's personality to breathe.
diff --git a/.editorconfig b/.editorconfig
deleted file mode 100644
index 5d126348..00000000
--- a/.editorconfig
+++ /dev/null
@@ -1,13 +0,0 @@
-# editorconfig.org
-root = true
-
-[*]
-indent_style = space
-indent_size = 2
-end_of_line = lf
-charset = utf-8
-trim_trailing_whitespace = true
-insert_final_newline = true
-
-[*.md]
-trim_trailing_whitespace = false
diff --git a/.env.example b/.env.example
index 887bc205..6ace7ae2 100644
--- a/.env.example
+++ b/.env.example
@@ -1,9 +1,6 @@
-VIGOTECH_MEMBERS_SOURCE = '/vigotech.json'
-VIGOTECH_MEMBERS_SOURCE_FILE = 'static/vigotech.json'
-VIGOTECH_MEMBERS_SOURCE_GENERATED = '/vigotech-generated.json'
-VIGOTECH_MEMBERS_SOURCE_GENERATED_FILE = 'static/vigotech-generated.json'
-VIGOTECH_FRIENDS_SOURCE = '/friends.json'
-MEETUP_API_BASE = 'http://api.meetup.com'
-YOUTUBE_API_KEY = '[YOUR YOUTUBE API KEY HERE]'
-GA = '[YOUR GOOGLE ANALYTICS PROPERTY ID HERE]'
-EVENTBRITE_OAUTH_TOKEN = '[YOUR EVENTBRITE PERSONAL OAUTH TOKEN HERE]'
+VIGOTECH_MOCK_EVENTS=true
+PUBLIC_BASE_PATH=
+PUBLIC_NOINDEX=false
+EVENTBRITE_OAUTH_TOKEN=
+YOUTUBE_API_KEY=
+GOOGLE_CALENDAR_API_KEY=
diff --git a/.eslintrc.js b/.eslintrc.js
deleted file mode 100644
index e60b7d6a..00000000
--- a/.eslintrc.js
+++ /dev/null
@@ -1,22 +0,0 @@
-module.exports = {
- root: true,
- env: {
- browser: true,
- node: true
- },
- parserOptions: {
- parser: 'babel-eslint'
- },
- extends: [
- 'plugin:vue/recommended'
- ],
- // required to lint *.vue files
- plugins: [
- 'vue'
- ],
- // add your custom rules here
- rules: {
- 'no-console': process.env.NODE_ENV === 'production' ? 'error' : 'off',
- 'no-debugger': process.env.NODE_ENV === 'production' ? 'error' : 'off'
- }
-}
diff --git a/.github/copilot-instructions.md b/.github/copilot-instructions.md
new file mode 100644
index 00000000..90ee7cf0
--- /dev/null
+++ b/.github/copilot-instructions.md
@@ -0,0 +1,40 @@
+# Project Development Guidelines
+
+## Testing Strategy
+
+- Use Vitest for unit tests and Playwright for e2e tests.
+- Keep unit tests focused and small.
+- Maintain 95% coverage thresholds for lines, statements, functions, and branches.
+
+## Folder Structure
+
+- Keep source code in `src/`.
+- Place reusable components under `src/components/`.
+- Place e2e tests under `playwright/`.
+- Place test setup in `test/`.
+
+## Code Organization
+
+- Keep one component per file when adding components.
+- Prefer named exports for utilities and components.
+- Keep files focused on a single responsibility.
+
+## Formatting
+
+- No semicolons.
+- Single quotes for strings.
+- Double quotes for JSX attributes.
+- Trailing commas in multi-line arrays and objects.
+- 100 character line width.
+- Arrow functions always use parentheses.
+
+## Linting
+
+- Use `oxlint` with `.oxlintrc.json`.
+- Ensure linting passes before commit.
+
+## Commit Convention
+
+- Follow Conventional Commits.
+- Types: feat, fix, docs, style, refactor, test, chore.
+- Format: `type(scope): description`.
diff --git a/.github/workflows/deploy-pages.yml b/.github/workflows/deploy-pages.yml
new file mode 100644
index 00000000..358d56c1
--- /dev/null
+++ b/.github/workflows/deploy-pages.yml
@@ -0,0 +1,142 @@
+name: Deploy Pages
+
+on:
+ push:
+ branches:
+ - main
+ workflow_dispatch:
+
+permissions:
+ contents: write
+ pages: write
+ id-token: write
+
+concurrency:
+ group: pages
+ cancel-in-progress: true
+
+env:
+ FORCE_JAVASCRIPT_ACTIONS_TO_NODE24: true
+ PUBLIC_BASE_PATH: ${{ vars.PUBLIC_BASE_PATH }}
+ PUBLIC_NOINDEX: ${{ vars.PUBLIC_NOINDEX || 'true' }}
+
+jobs:
+ refresh-data:
+ if: github.actor != 'github-actions[bot]'
+ permissions:
+ contents: write
+ runs-on: ubuntu-latest
+ steps:
+ - name: Checkout
+ uses: actions/checkout@v4
+ with:
+ fetch-depth: 0
+
+ - name: Setup Node.js
+ uses: actions/setup-node@v4
+ with:
+ node-version: '22'
+
+ - name: Setup pnpm
+ uses: pnpm/action-setup@v4
+ with:
+ version: 10
+
+ - name: Get pnpm store directory
+ id: pnpm-cache
+ shell: bash
+ run: echo "STORE_PATH=$(pnpm store path)" >> "$GITHUB_OUTPUT"
+
+ - name: Setup pnpm cache
+ uses: actions/cache@v4
+ with:
+ path: ${{ steps.pnpm-cache.outputs.STORE_PATH }}
+ key: ${{ runner.os }}-pnpm-store-${{ hashFiles('**/pnpm-lock.yaml') }}
+ restore-keys: |
+ ${{ runner.os }}-pnpm-store-
+
+ - name: Install dependencies
+ run: pnpm install --frozen-lockfile
+
+ - name: Generate vigotech data
+ run: pnpm generate:data
+ env:
+ EVENTBRITE_OAUTH_TOKEN: ${{ secrets.EVENTBRITE_OAUTH_TOKEN }}
+ YOUTUBE_API_KEY: ${{ secrets.YOUTUBE_API_KEY }}
+
+ - name: Sync Astro content types
+ run: pnpm astro sync
+
+ - name: Format generated content
+ run: pnpm format src/content/events src/content/videos
+
+ - name: Commit generated data
+ run: |
+ if git diff --quiet -- public/vigotech-generated.json src/content/videos src/content/events; then
+ echo "No generated changes to commit"
+ exit 0
+ fi
+
+ git config user.name "github-actions[bot]"
+ git config user.email "41898282+github-actions[bot]@users.noreply.github.com"
+ git add public/vigotech-generated.json src/content/videos src/content/events
+ git commit -m "chore: refresh generated community history"
+ git push
+
+ build:
+ needs: refresh-data
+ runs-on: ubuntu-latest
+ steps:
+ - name: Checkout
+ uses: actions/checkout@v4
+
+ - name: Setup Node.js
+ uses: actions/setup-node@v4
+ with:
+ node-version: '22'
+
+ - name: Setup pnpm
+ uses: pnpm/action-setup@v4
+ with:
+ version: 10
+
+ - name: Get pnpm store directory
+ id: pnpm-cache
+ shell: bash
+ run: echo "STORE_PATH=$(pnpm store path)" >> "$GITHUB_OUTPUT"
+
+ - name: Setup pnpm cache
+ uses: actions/cache@v4
+ with:
+ path: ${{ steps.pnpm-cache.outputs.STORE_PATH }}
+ key: ${{ runner.os }}-pnpm-store-${{ hashFiles('**/pnpm-lock.yaml') }}
+ restore-keys: |
+ ${{ runner.os }}-pnpm-store-
+
+ - name: Install dependencies
+ run: pnpm install --frozen-lockfile
+
+ - name: Generate vigotech data
+ run: pnpm generate:data
+ env:
+ EVENTBRITE_OAUTH_TOKEN: ${{ secrets.EVENTBRITE_OAUTH_TOKEN }}
+ YOUTUBE_API_KEY: ${{ secrets.YOUTUBE_API_KEY }}
+
+ - name: Build site
+ run: pnpm build
+
+ - name: Upload Pages artifact
+ uses: actions/upload-pages-artifact@v3
+ with:
+ path: ./dist
+
+ deploy:
+ needs: build
+ runs-on: ubuntu-latest
+ environment:
+ name: github-pages
+ url: ${{ steps.deployment.outputs.page_url }}
+ steps:
+ - name: Deploy to GitHub Pages
+ id: deployment
+ uses: actions/deploy-pages@v4
diff --git a/.github/workflows/gh-pages.yml b/.github/workflows/gh-pages.yml
deleted file mode 100644
index 73d3214f..00000000
--- a/.github/workflows/gh-pages.yml
+++ /dev/null
@@ -1,51 +0,0 @@
-name: GH-pages
-
-on:
- schedule:
- - cron: "* 16 * * *"
- push:
- branches:
- - source
-
-jobs:
- pages:
- runs-on: ubuntu-latest
- steps:
- - uses: actions/checkout@v2
- - name: Use Node.js 12.x
- uses: actions/setup-node@v1
- with:
- node-version: '12.x'
- - name: Cache NPM dependencies
- uses: actions/cache@v2
- with:
- path: node_modules
- key: ${{ runner.OS }}-npm-cache
- restore-keys: |
- ${{ runner.OS }}-npm-cache
- - name: Install Dependencies
- run: yarn install
- - name: Prepare json
- run: yarn prepare-json
- env:
- VIGOTECH_MEMBERS_SOURCE: /vigotech.json
- VIGOTECH_MEMBERS_SOURCE_FILE: static/vigotech.json
- VIGOTECH_MEMBERS_SOURCE_GENERATED: /vigotech-generated.json
- VIGOTECH_MEMBERS_SOURCE_GENERATED_FILE: static/vigotech-generated.json
- VIGOTECH_FRIENDS_SOURCE: /friends.json
- MEETUP_API_BASE: 'http://api.meetup.com'
- EVENTBRITE_OAUTH_TOKEN: ${{ secrets.EVENTBRITE_OAUTH_TOKEN }}
- YOUTUBE_API_KEY: ${{ secrets.YOUTUBE_API_KEY }}
- - name: Build
- run: yarn generate:gh-pages
- env:
- GA: 'UA-98368785-1'
- VIGOTECH_FRIENDS_SOURCE: /friends.json
- VIGOTECH_MEMBERS_SOURCE_GENERATED: /vigotech-generated.json
- VIGOTECH_MEMBERS_SOURCE: /vigotech.json
- - name: Deploy
- uses: peaceiris/actions-gh-pages@v3
- with:
- github_token: ${{ secrets.GITHUB_TOKEN }}
- publish_dir: ./dist
- publish_branch: master
diff --git a/.gitignore b/.gitignore
index 31978748..ca273981 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,83 +1,38 @@
-# Created by .ignore support plugin (hsz.mobi)
-### Node template
-# Logs
-logs
+# build output
+dist/
+build/
+# generated types
+.astro/
+
+# dependencies
+node_modules/
+
+# logs
*.log
npm-debug.log*
yarn-debug.log*
yarn-error.log*
+pnpm-debug.log*
-# Runtime data
-pids
-*.pid
-*.seed
-*.pid.lock
-
-# Directory for instrumented libs generated by jscoverage/JSCover
-lib-cov
-
-# Coverage directory used by tools like istanbul
-coverage
-
-# nyc test coverage
-.nyc_output
+# testing
+coverage/
+playwright-report/
+test-results/
-# Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files)
-.grunt
-
-# Bower dependency directory (https://bower.io/)
-bower_components
-
-# node-waf configuration
-.lock-wscript
-
-# Compiled binary addons (https://nodejs.org/api/addons.html)
-build/Release
-
-# Dependency directories
-node_modules/
-jspm_packages/
+# vite cache
+.vite/
-# TypeScript v1 declaration files
-typings/
+# temporary files
+*.tmp
+*.temp
-# Optional npm cache directory
-.npm
-# Optional eslint cache
-.eslintcache
-
-# Optional REPL history
-.node_repl_history
-
-# Output of 'npm pack'
-*.tgz
-
-# Yarn Integrity file
-.yarn-integrity
-
-# dotenv environment variables file
+# environment variables
.env
+.env.production
-# parcel-bundler cache (https://parceljs.org/)
-.cache
-
-# next.js build output
-.next
-
-# nuxt.js build output
-.nuxt
-
-# Nuxt generate
-dist
-
-# vuepress build output
-.vuepress/dist
-
-# Serverless directories
-.serverless
-
-# IDE
-.idea
+# macOS-specific files
+.DS_Store
-/static/vigotech-generated.json
+# jetbrains setting folder
+.idea/
diff --git a/.oxfmtrc.json b/.oxfmtrc.json
new file mode 100644
index 00000000..c930a9e3
--- /dev/null
+++ b/.oxfmtrc.json
@@ -0,0 +1,8 @@
+{
+ "semi": false,
+ "singleQuote": true,
+ "jsxSingleQuote": false,
+ "trailingComma": "all",
+ "printWidth": 100,
+ "arrowParens": "always"
+}
diff --git a/.oxlintrc.json b/.oxlintrc.json
new file mode 100644
index 00000000..f462dd89
--- /dev/null
+++ b/.oxlintrc.json
@@ -0,0 +1,5 @@
+{
+ "$schema": "https://raw.githubusercontent.com/oxc-project/oxc/main/npm/oxlint/configuration_schema.json",
+ "plugins": ["typescript", "unicorn", "jsx-a11y"],
+ "rules": {}
+}
diff --git a/.stitch/code-conduct-mobile.html b/.stitch/code-conduct-mobile.html
new file mode 100644
index 00000000..bc953fda
--- /dev/null
+++ b/.stitch/code-conduct-mobile.html
@@ -0,0 +1,365 @@
+
+
+
+
+
+
+ Code of Conduct | The Editorial Node
+
+
+
+
+
+
+
+
+
+
+
+ The Editorial Node
+
+
+ menu
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Our Digital Ethos
+
+ "We view code as literature and communities as living ecosystems. Respect the craft, but
+ value the creator above all."
+
+
+
+
+
+
+
+
+ Node Visual Archive // 2024 / VigoTech
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/.stitch/code-conduct-mobile.png b/.stitch/code-conduct-mobile.png
new file mode 100644
index 00000000..c999d164
Binary files /dev/null and b/.stitch/code-conduct-mobile.png differ
diff --git a/.stitch/groups-mobile.html b/.stitch/groups-mobile.html
new file mode 100644
index 00000000..51bacda7
--- /dev/null
+++ b/.stitch/groups-mobile.html
@@ -0,0 +1,611 @@
+
+
+
+
+
+
+ Groups Directory | VigoTech Pulse
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Ecosystem Directory
+
+ Collective
+ Intelligence.
+
+
+ Discover the vibrant nodes of the Vigo technology scene. From niche hardware hackers
+ to large-scale software communities.
+
+
+
+
+
+ Active
+
+
+ Archived
+
+
+
+
+
+
+
+
+
+ search
+
+
+
+
+ Frontend
+
+
+ DevOps
+
+
+ Design
+
+
+ Hardware
+
+
+
+
+
+
+
+
+
+
+ Active
+
+
+
+
+
+
+
+
+
VigoJS
+
+ The heartbeat of the Javascript ecosystem in Galicia. Monthly meetups covering React,
+ Vue, Node, and everything in between.
+
+
+
+
+
+ Join Community
+ arrow_forward
+
+
+
+
+
+
+
+ Active
+
+
+
+
+
+
+
+
+
Python Vigo
+
+ Dedicated to the snake. Data science, automation, and backend engineering enthusiasts
+ gathering to share knowledge.
+
+
+
+
+
+ Join Community
+ arrow_forward
+
+
+
+
+
+
+
+ Dormant
+
+
+
+
+
+
+
+
+
IoT Galicia
+
+ Connecting the physical world. Embedded systems, Arduino, Raspberry Pi, and industrial
+ automation discussions.
+
+
+
+
+
+ View Archive
+ history
+
+
+
+
+
+
+
+ Active
+
+
+
+
+
+
+
+
+
PHPVigo
+
+ The web veterans. Focus on Laravel, Symfony, and modern backend architectures in the
+ PHP universe.
+
+
+
+
+
+ Join Community
+ arrow_forward
+
+
+
+
+
+
+
+ Active
+
+
+
+
+
+
+
+
+
UX Vigo
+
+ Where design meets technology. Exploring accessibility, user psychology, and modern
+ interface trends.
+
+
+
+
+
+ Join Community
+ arrow_forward
+
+
+
+
+
+
+
+ Active
+
+
+
+
+
+
+
+
+
Agile Vigo
+
+ Optimizing workflows. Scrum, Kanban, Lean and XP practices discussed by local project
+ leaders and devs.
+
+
+
+
+
+ Join Community
+ arrow_forward
+
+
+
+
+
+
+
+
+
+ Can't find your node?
+ Create it.
+
+
+ VigoTech Pulse is built on collaboration. If you have a community or want to start one,
+ we provide the platform and the reach.
+
+
+
+ Submit New Group
+
+
+ Developer Manifesto
+
+
+
+
+
+
+
+
+
+ add
+
+
+
diff --git a/.stitch/groups-mobile.png b/.stitch/groups-mobile.png
new file mode 100644
index 00000000..bc3dfcc0
Binary files /dev/null and b/.stitch/groups-mobile.png differ
diff --git a/.stitch/home-desktop.html b/.stitch/home-desktop.html
new file mode 100644
index 00000000..58293331
--- /dev/null
+++ b/.stitch/home-desktop.html
@@ -0,0 +1,655 @@
+
+
+
+
+
+
+ VigoTech Alliance | The Editorial Node
+
+
+
+
+
+
+
+
+
+
+
+ VigoTech Alliance
+
+
+
+
+ search
+
+
+ Get Involved
+
+
+
+
+
+
+
+
+
+
+ The Technical
+ Pulse of Galicia.
+
+
+ A federated ecosystem of developer communities, hackers, and innovators. We bridge
+ technical precision with human-centric connection to showcase the local movement.
+
+
+
+ Explore Ecosystem
+
+
+
+
+
+
+
+
+
+
+
+
+ +4k
+
+
+
+
+
+
+
+ hub
+
+
+
Status: Active
+
+ 15+ Member Communities
+
+
+ Connecting Python, JavaScript, DevOps, and UI experts under one unified banner.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ terminal
+
+
+ 24
+ Oct
+
+
+
+ Rust in Production: Lessons Learned
+
+
+
+ group
+ Rust Vigo
+
+
+ schedule
+ 19:00 - 21:00 CEST
+
+
+ location_on
+ MARCO Museum, 2nd Floor
+
+
+
+
+
+
+
+
+ architecture
+
+
+ 28
+ Oct
+
+
+
+ Design Systems for Scale
+
+
+
+ group
+ UI/UX Vigo
+
+
+ schedule
+ 18:30 - 20:30 CEST
+
+
+ location_on
+ Impact Hub Vigo
+
+
+
+
+
+
+
+
+ cloud
+
+
+ 02
+ Nov
+
+
+
+ Serverless Deep Dive
+
+
+
+ group
+ GDG Vigo
+
+
+ schedule
+ 10:00 - 13:00 CEST
+
+
+ location_on
+ Online Stream
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Active Communities
+
+
+ Our alliance is composed of diverse technical groups sharing knowledge and driving
+ innovation across the northwest coast. Discover your tribe.
+
+
+
Want to list your group?
+
+ Join the alliance and help us grow the local developer ecosystem together.
+
+
+ Apply for membership add
+
+
+
+
+
+
+
+
+
+ code
+
+
+
Python Vigo
+
1.2k Members
+
+
+
+ The most active Python community in Galicia, hosting monthly meetups and
+ workshops.
+
+
+
+
+
+
+
+ Focusing on modern JavaScript frameworks, web standards, and high-performance
+ frontend.
+
+
+
+
+
+
+
+ security
+
+
+
HackersVigo
+
540 Members
+
+
+
+ Cybersecurity enthusiasts sharing tools, techniques, and organizing CTF events.
+
+
+
+
+
+
+
+ brush
+
+
+
UI/UX Vigo
+
720 Members
+
+
+
+ Where design meets engineering. Discussing product design, research, and user
+ experience.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Stay in the Loop
+
+
+ Get monthly updates about all community events, new video releases, and job
+ opportunities within the VigoTech network.
+
+
+
+
+
+
+
+
+
+
diff --git a/.stitch/home-desktop.png b/.stitch/home-desktop.png
new file mode 100644
index 00000000..032dcf4a
Binary files /dev/null and b/.stitch/home-desktop.png differ
diff --git a/.stitch/video-library-mobile.html b/.stitch/video-library-mobile.html
new file mode 100644
index 00000000..22ad7db3
--- /dev/null
+++ b/.stitch/video-library-mobile.html
@@ -0,0 +1,500 @@
+
+
+
+
+
+
+ Video Library | The Editorial Node
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ CURATED KNOWLEDGE
+
+ Video Library .
+
+
+
+
+
+
+
+
+ All Groups
+
+
+ PythonVigo
+
+
+ VigoJS
+
+
+ PHPVigo
+
+
+ AgileVigo
+
+
+
+
+
+ calendar_month
+ Sort by Date
+
+
+
+ filter_list
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 45:22
+
+
+
+
+
+
+
+
VigoJS
+
+
+ Mastering React Server Components in 2024
+
+
+ Oct 12, 2023
+
+ WATCH NOW
+ arrow_forward
+
+
+
+
+
+
+
+
+
+
+ 1:12:05
+
+
+
+
+
+
+
+
PythonVigo
+
+
+ Advanced Asyncio Patterns for Production
+
+
+ Sep 28, 2023
+
+ WATCH NOW
+ arrow_forward
+
+
+
+
+
+
+
+
+
+
+ 38:15
+
+
+
+
+
+
+
+
PHPVigo
+
+
+ Modern Laravel: Beyond the Basics
+
+
+ Aug 15, 2023
+
+ WATCH NOW
+ arrow_forward
+
+
+
+
+
+
+
+
+ Featured Workshop Series
+
+
+
+
+
INTENSIVE
+
+ The Architecture of Scalable Microservices
+
+
+ A 4-part deep dive into distributed systems, event-sourcing, and kubernetes
+ deployment strategies for high-growth teams.
+
+
+ ACCESS SERIES
+
+
+
+
+
+
+
+
auto_awesome
+
+
New: AI Ethics in Coding
+
+ Navigating the gray areas of copilot and generative models in professional dev
+ workflows.
+
+
Listen to Panel
+
+
+
+
+
+
+
+
+ video_library
+ Library
+
+
+ groups
+ Groups
+
+
+ calendar_month
+ Events
+
+
+ person
+ Profile
+
+
+
+
+ upload
+
+
+
diff --git a/.stitch/video-library-mobile.png b/.stitch/video-library-mobile.png
new file mode 100644
index 00000000..32d2709a
--- /dev/null
+++ b/.stitch/video-library-mobile.png
@@ -0,0 +1,11 @@
+
+
+
+
+ Error 400 (Bad Request)!!1
+
+
+ 400. That’s an error.
+
Your client has issued a malformed or illegal request. That’s all we know.
diff --git a/.vscode/extensions.json b/.vscode/extensions.json
new file mode 100644
index 00000000..68c6154c
--- /dev/null
+++ b/.vscode/extensions.json
@@ -0,0 +1,4 @@
+{
+ "recommendations": ["astro-build.astro-vscode", "oxc.oxc-vscode"],
+ "unwantedRecommendations": []
+}
diff --git a/.vscode/launch.json b/.vscode/launch.json
new file mode 100644
index 00000000..d6422097
--- /dev/null
+++ b/.vscode/launch.json
@@ -0,0 +1,11 @@
+{
+ "version": "0.2.0",
+ "configurations": [
+ {
+ "command": "./node_modules/.bin/astro dev",
+ "name": "Development server",
+ "request": "launch",
+ "type": "node-terminal"
+ }
+ ]
+}
diff --git a/.vscode/settings.json b/.vscode/settings.json
new file mode 100644
index 00000000..eb556f40
--- /dev/null
+++ b/.vscode/settings.json
@@ -0,0 +1,30 @@
+{
+ "editor.formatOnSave": true,
+ "editor.defaultFormatter": "oxc.oxc-vscode",
+ "editor.codeActionsOnSave": {
+ "source.fixAll": "explicit"
+ },
+ "oxc.enable": true,
+ "oxc.lint.enable": true,
+ "oxc.format.enable": true,
+ "peacock.color": "#e84a5f",
+ "workbench.colorCustomizations": {
+ "activityBar.activeBackground": "#ee7787",
+ "activityBar.background": "#ee7787",
+ "activityBar.foreground": "#15202b",
+ "activityBar.inactiveForeground": "#15202b99",
+ "activityBarBadge.background": "#9bf18e",
+ "activityBarBadge.foreground": "#15202b",
+ "commandCenter.border": "#e7e7e799",
+ "sash.hoverBorder": "#ee7787",
+ "statusBar.background": "#e84a5f",
+ "statusBar.foreground": "#e7e7e7",
+ "statusBarItem.hoverBackground": "#ee7787",
+ "statusBarItem.remoteBackground": "#e84a5f",
+ "statusBarItem.remoteForeground": "#e7e7e7",
+ "titleBar.activeBackground": "#e84a5f",
+ "titleBar.activeForeground": "#e7e7e7",
+ "titleBar.inactiveBackground": "#e84a5f99",
+ "titleBar.inactiveForeground": "#e7e7e799"
+ }
+}
diff --git a/LICENSE b/LICENSE
deleted file mode 100644
index bc9a1981..00000000
--- a/LICENSE
+++ /dev/null
@@ -1,29 +0,0 @@
-BSD 3-Clause License
-
-Copyright (c) 2018, Sergio Carracedo Martinez
-All rights reserved.
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions are met:
-
-* Redistributions of source code must retain the above copyright notice, this
- list of conditions and the following disclaimer.
-
-* Redistributions in binary form must reproduce the above copyright notice,
- this list of conditions and the following disclaimer in the documentation
- and/or other materials provided with the distribution.
-
-* Neither the name of the copyright holder nor the names of its
- contributors may be used to endorse or promote products derived from
- this software without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
-AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
-DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
-FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
-SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
-CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
-OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/README.md b/README.md
index 1ec00516..b81ec505 100644
--- a/README.md
+++ b/README.md
@@ -1,90 +1,70 @@
-# vigotech.github.io
-
-> VigoTech Alliance Website
-
-## Build Setup
-
-``` bash
-# install dependencies
-$ yarn
-
-# rename .env.example to .env and edit using your own config
-
-# prepare required static/vigotech-generated.json
-$ yarn run prepare-json
-
-# serve with hot reload at localhost:3000
-$ yarn run dev
-
-# generate static project
-$ yarn run generate
-```
-
-## Instruccións para engadir información
-
-En primeiro lugar para engadir ou editar un membro o grupo, debe modificarse únicamente *static/vigotech.json*
-Este fichero ten un *schema* no fichero *static/vigotech-schema.json* cando se xere a parte de front mediante ```yarn prepare``` este validarase polo que debe asegurarse que estea correcto.
-
-A estructura dun membro (como exemplo collemos un existente) é:
-
-```
-"aindustriosa": {
- "name": "A Industriosa",
- "logo": "https://vigotech.org/images/aindustriosa.png",
- "links": {
- "web": "https://aindustriosa.org/",
- "twitter": "https://twitter.com/aindustriosa",
- "meetup": "https://www.meetup.com/es-ES/AIndustriosa/",
- "youtube": "https://www.youtube.com/channel/UC9DPKfcLiNd7SEU-QLlIG7A"
- },
- "events": {
- "type": "meetup",
- "meetupid": "AIndustriosa"
- },
- "videos": [
- {
- "type": "youtube",
- "channel_id": "UC9DPKfcLiNd7SEU-QLlIG7A"
- }
- ]
- }
-```
-
-O apartado *events* pode ter duas formas
-
-* Para eventos que se extraen mediante a api de Meetup
-```
-"events": {
- "type": "meetup",
- "meetupid": "AIndustriosa"
-}
-```
-* Para eventos que se extraen mediante a api de Eventbrite
-```
-"events": {
- "type": "eventbrite",
- "eventbriteid": "17365087639"
-}
-```
-* Ou para eventos extraido dun json externo
-```
-"events": {
- "type": "json",
- "source": "https://www.python-vigo.es/events.json"
-},
-```
-
-
-Coa forma
-```
-{
- "title": "Reunión del Grupo el 18/11/2018",
- "date": 1542569580000,
- "url": "https://www.python-vigo.es/posts/reunion-del-grupo-el-20181018/"
-}
-
-```
+# VigoTech Website (Astro)
+This project is the Astro migration of the VigoTech website.
+## Commands
+| Command | Action |
+| ----------------------- | ---------------------------------------- |
+| `pnpm install` | Install dependencies |
+| `pnpm dev` | Start local dev server |
+| `pnpm dev --mockEvents` | Start dev with synthetic upcoming events |
+| `pnpm generate:data` | Refresh `public/vigotech-generated.json` |
+| `pnpm check` | Run Astro checks |
+| `pnpm build` | Type-check and build static site |
+## Data source
+
+By default, the site reads source files from `public/`:
+
+- `public/vigotech.json`
+- `public/vigotech-generated.json`
+- `public/friends.json`
+
+Run `pnpm generate:data` to rebuild `public/vigotech-generated.json` from
+`public/vigotech.json` using the legacy VigoTech source fetchers.
+
+## Environment variables
+
+- `VIGOTECH_MOCK_EVENTS`
+ - Used in development to generate synthetic upcoming events when real events are not available.
+ - Automatically set by `pnpm dev --mockEvents`.
+
+- `VIGOTECH_CONFIG_DATA_DIR`
+ - Optional override for local source JSON directory.
+ - Default: `public`.
+ - Used for `vigotech.json` and `friends.json`.
+
+- `PUBLIC_BASE_PATH`
+ - Optional base path for subpath deployments.
+ - Example: `PUBLIC_BASE_PATH=vigotech-astro` produces URLs under `/vigotech-astro/`.
+ - Leave empty for root deployments.
+
+- `PUBLIC_NOINDEX`
+ - Optional search-engine opt-out for non-production deployments.
+ - Set to `true` to emit ` ` on every page.
+ - Recommended for temporary test deployments.
+
+- `VIGOTECH_GENERATED_DATA_DIR`
+ - Optional override for generated JSON directory.
+ - Default: `public`.
+ - Used only for `vigotech-generated.json`.
+
+- `EVENTBRITE_OAUTH_TOKEN`
+ - Optional token used while generating upcoming events from Eventbrite.
+ - Used by `pnpm generate:data` and the Pages workflow.
+
+- `YOUTUBE_API_KEY`
+ - Optional API key used while generating `videoList` entries from YouTube.
+ - Used by `pnpm generate:data` and the Pages workflow.
+
+- `GOOGLE_CALENDAR_API_KEY`
+ - Used by `/api/calendar.json` to fetch events from VigoTech public Google Calendar.
+ - If omitted, the Axenda block still renders and keeps the iCal download link, but no live events are shown.
+
+## Group status
+
+- Group active/inactive is now manual.
+- Set `inactive: true` in source data for archived groups.
+
+Copy `.env.example` to `.env` and customize values for local work.
diff --git a/assets/README.md b/assets/README.md
deleted file mode 100644
index 34766f93..00000000
--- a/assets/README.md
+++ /dev/null
@@ -1,7 +0,0 @@
-# ASSETS
-
-**This directory is not required, you can delete it if you don't want to use it.**
-
-This directory contains your un-compiled assets such as LESS, SASS, or JavaScript.
-
-More information about the usage of this directory in [the documentation](https://nuxtjs.org/guide/assets#webpacked).
diff --git a/assets/_calendar.scss b/assets/_calendar.scss
deleted file mode 100644
index d71bac07..00000000
--- a/assets/_calendar.scss
+++ /dev/null
@@ -1,26 +0,0 @@
-#calendar {
- text-align: center;
-
- .embed-responsive {
- display: block;
- margin: 0 auto 2rem auto;
- width: 80%;
- max-width: 1200px;
- word-break: break-word;
-
-
- @include box-shadow(0, 0, 30px, rgba($black, 0.5));
-
- @include media($xs) {
- width: 100%;
- padding-bottom: 100%;
- }
-
- &, .embed-responsive-item {
- @include media($xs) {
- }
- }
-
-
- }
-}
diff --git a/assets/_conversation.scss b/assets/_conversation.scss
deleted file mode 100644
index c8f34593..00000000
--- a/assets/_conversation.scss
+++ /dev/null
@@ -1,27 +0,0 @@
-#conversation {
- .section-content {
- p {
- font-size: 25px;
- margin: 0 auto 1em auto;
- max-width: 600px;
- }
- }
-
- .social {
- text-align: center;
- margin-bottom: 40px;
-
- a {
- color: $black;
- margin: 0 10px 10px 10px;
- @include transition(all, .2s);
-
- &:hover {
- @include scale(1.2);
- }
- }
- }
- .col {
- margin-bottom: 40px;
- }
-}
diff --git a/assets/_cover.scss b/assets/_cover.scss
deleted file mode 100644
index 8a2416c1..00000000
--- a/assets/_cover.scss
+++ /dev/null
@@ -1,130 +0,0 @@
-#cover {
- background: $primary-color url(/bg.jpg) no-repeat center center;
- background-size: cover;
- background-attachment: fixed;
- z-index: 9999;
- position: relative;
-
- .content-wrapper {
- min-height: 100vh;
- }
- .content {
- //@include vertical-align();
- }
-
- .logo {
- margin: 0 auto 40px auto;
- width: 200px;
- display: block;
- }
- h1, h2 {
- color: $white;
- text-align: center;
- }
-
- h1 {
- font-size: 80px;
- margin: 0 auto 40px auto;
- @include media($xs) {
- font-size: 50px;
- }
- }
-
- h2 {
- font-size: 35px;
- max-width: 600px;
- margin: auto;
-
- @include media($xs) {
- font-size: 25px;
- }
- }
-
- .down-wrapper {
- text-align: center;
- .down {
- @include transition(all, .2s);
- color: rgba($white, .5);
- font-size: 80px;
- &:hover {
- color: rgba($white, 1);
- @include scale(1.2);
- }
- }
- }
-
- .vigotech-next-event {
- max-width: 600px;
- background: $white;
- padding: 15px;
- margin: 30px auto;
- h4 {
- margin-bottom: 15px;
- strong {
- color: $primary-color
- }
- }
-
- .wrapper {
- display: flex;
- margin-bottom: 15px;
- padding-bottom: 15px;
- border-bottom: 1px solid $primary-color;
- &:last-child {
- border-bottom: 0;
- margin-bottom: 0;
- }
- }
-
- .logo-wrapper {
- width: 70px;
- position: relative;
- .member-logo {
- max-width: 100%;
- }
- }
- .next-event-content {
- padding: 10px 0 0 15px;
- color: $black;
-
- h5, h6 {
- font-size: 16px;
- }
-
- a {
- text-decoration: none;
- color: $black;
-
- h6 {
- color: #666;
- }
-
- strong {
- color: $primary-color;
- }
- }
- }
-
- &.vigotech-next-event-active {
- padding: 10px;
- border: 10px solid $primary-color;
- animation-duration: 1.2s;
- animation-iteration-count: infinite;
- animation-name: highlightBorder;
- }
- }
-}
-
-@keyframes highlightBorder {
- 0% {
- border-color: $black;
- }
-
- 50% {
- border-color: $primary-color;
- }
-
- 100% {
- border-color: $black;
- }
-}
diff --git a/assets/_docs.scss b/assets/_docs.scss
deleted file mode 100644
index 8b44928a..00000000
--- a/assets/_docs.scss
+++ /dev/null
@@ -1,12 +0,0 @@
-#docs {
- .col {
- margin-bottom: 30px;
-
- a {
- height: 100%;
- display: flex;
- align-items: center;
- justify-content: center;
- }
- }
-}
diff --git a/assets/_elements.scss b/assets/_elements.scss
deleted file mode 100644
index 4318f376..00000000
--- a/assets/_elements.scss
+++ /dev/null
@@ -1,36 +0,0 @@
-.btn {
- display: inline-block;
- background: $primary-color;
- padding: 5px 10px;
- text-align: center;
- color: $white;
- font-size: 16px;
- line-height: 1.1em;
- text-decoration: none;
-
- @include transition(all, .2s);
-
- &:hover {
- color: $white;
- text-decoration: none;
- background: $black;
- }
-
- &.btn-white {
- background: $white;
- color: $black;
- &:hover {
- background: $black;
- color: $white;
- }
- }
-
- &.btn-block {
- display: block;
- }
-
- &.btn-lg {
- font-size: 20px;
- padding: 10px 15px;
- }
-}
diff --git a/assets/_footer.scss b/assets/_footer.scss
deleted file mode 100644
index 2f5f6482..00000000
--- a/assets/_footer.scss
+++ /dev/null
@@ -1,31 +0,0 @@
-#page-footer {
- background: $gray;
- text-align: center;
- padding: 15px;
- color: $light-gray;
- position: fixed;
- bottom: 0;
- left: 0;
- right: 0;
- display: flex;
- justify-content: center;
- align-items: center;
- z-index: 9998;
-
- .social {
- margin: 10px;
-
- a {
- color: $white;
- margin: 0 3px;
-
- i {
- font-size: 26px;
- }
- }
- }
-
- @include media($xs) {
- padding: 15px 10px;
- }
-}
diff --git a/assets/_friends.scss b/assets/_friends.scss
deleted file mode 100644
index 84abd5e2..00000000
--- a/assets/_friends.scss
+++ /dev/null
@@ -1,49 +0,0 @@
-.vigotech-friend {
- margin-bottom: 30px;
-
- .logo-wrapper {
- text-align: center;
-
- .logo-content {
- display: inline-block;
- position: relative;
- }
- }
-
- .name {
- display: block;
- text-align: center;
- font-size: 10px;
- line-height: 1.1em;
- margin: 0 0 7px 0;
- font-weight: normal;
-
- a {
- color: $white;
- text-decoration: none;
- }
- }
-
- .logo-wrapper {
- margin-bottom: 5px;
- position: relative;
- .square-bg {
- width: 160px;
- max-width: 100%;
- height: auto;
- }
- .logo {
- max-width: 160px;
- width: 100%;
- display: block;
- left: 0;
- right: 0;
- top: 50%;
- margin: auto;
- position: absolute;
- -webkit-transform: translateY(-50%);
- -ms-transform: translateY(-50%);
- transform: translateY(-50%);
- }
- }
-}
diff --git a/assets/_layout.scss b/assets/_layout.scss
deleted file mode 100644
index d1c7beb9..00000000
--- a/assets/_layout.scss
+++ /dev/null
@@ -1,174 +0,0 @@
-@import url('https://fonts.googleapis.com/css?family=Raleway');
-
-body {
- background: $white;
- font-family: $primary-font;
- box-sizing: border-box;
- padding: 0 0 30px 0;
- margin: 0;
- font-weight: 200;
-}
-
-html {
- font-family: 'Raleway', sans-serif, Roboto, 'Helvetica Neue', Arial, sans-serif;
- font-size: 16px;
- word-spacing: 1px;
- -ms-text-size-adjust: 100%;
- -webkit-text-size-adjust: 100%;
- -moz-osx-font-smoothing: grayscale;
- -webkit-font-smoothing: antialiased;
- box-sizing: border-box;
-
- *,
- *:before,
- *:after {
- box-sizing: border-box;
- margin: 0;
- }
-}
-
-img {
- max-width: 100%;
- height: auto;
-}
-
-
-.page-section {
- padding: 40px 15px;
- color: $black;
- h2.section-title {
- text-align: center;
- font-size: 50px;
- margin: 10px 0 35px 0;
- padding: 10px 15px;
- background: $white;
-
- @include media ($xs) {
- font-size: 30px;
- }
- }
-
- &.red-bg {
- background: $primary-color;
- color: $white;
- h2.section-title {
- background: $primary-color;
- }
- }
-
- .section-content {
- &.section-content-center {
- text-align: center;
- }
-
- p {
- margin-bottom: 1.4em;
- }
- }
-}
-
-.page-header {
- padding: 10px 15px;
- background: $primary-color;
- color: $white;
- margin-bottom: 80px;
-
- .page-header-content {
- align-items: center;
- display: flex;
- }
-
- .logo {
- padding-left: 20px;
- }
-
- .spacer {
- flex: 1;
- }
-
- h1.page-title {
- text-align: center;
- font-size: 45px;
- padding: 0 15px;
-
- @include media ($xs) {
- font-size: 20px;
- line-height: 1.1em;
- }
- }
-
- @include media ($xs) {
- margin-bottom: 0;
- .logo {
- padding-left: 0;
- width: 50px;
- }
- }
-}
-
-.wrap {
- box-sizing: border-box;
- max-width: 1200px;
- margin: 0 auto;
-}
-
-.layout {
- display: flex;
- min-height: 100vh;
- flex-direction: column;
-}
-
-// Embeds responsive
-//
-// Credit: Nicolas Gallagher and SUIT CSS.
-
-.embed-responsive {
- position: relative;
- display: block;
- height: 0;
- padding: 0;
- overflow: hidden;
-
- .video-js,
- .embed-responsive-item,
- iframe,
- embed,
- object,
- video {
- position: absolute;
- top: 0;
- left: 0;
- bottom: 0;
- height: 100%;
- width: 100%;
- border: 0;
- }
-}
-
-// Modifier class for 16:9 aspect ratio
-.embed-responsive-16by9 {
- padding-bottom: 56.25%;
-}
-
-// Modifier class for 4:3 aspect ratio
-.embed-responsive-4by3 {
- padding-bottom: 75%;
-}
-
-
-
-@include media($xs) {
- .container-fluid {
- padding: 0;
- }
-
- .page-header-content {
- &.row {
- margin: 0;
- }
- }
-}
-
-vue-cookie-accept-decline {
- display: none;
-}
diff --git a/assets/_made-with.scss b/assets/_made-with.scss
deleted file mode 100644
index 092c45c5..00000000
--- a/assets/_made-with.scss
+++ /dev/null
@@ -1,80 +0,0 @@
-@font-face {
- font-family: 'Vigotech';
- src: url('fonts/vigotech.eot?qv79y9');
- src: url('fonts/vigotech.eot?qv79y9#iefix') format('embedded-opentype'),
- url('fonts/vigotech.ttf?qv79y9') format('truetype'),
- url('fonts/vigotech.woff?qv79y9') format('woff'),
- url('fonts/vigotech.svg?qv79y9#icomoon') format('svg');
- font-weight: normal;
- font-style: normal;
-}
-
-[class^="vt-"], [class*=" vt-"] {
- font-family: 'Vigotech' !important;
- speak: none;
- font-style: normal;
- font-weight: normal;
- font-variant: normal;
- text-transform: none;
- line-height: 1;
- -webkit-font-smoothing: antialiased;
- -moz-osx-font-smoothing: grayscale;
-}
-
-
-.vt-pinecone:before {
- content: "\e900";
-}
-
-
-
-.vigotech-claim {
- font-family: 'Raleway', sans-serif;
- font-size: 16px;
- color: #666;
- font-weight: 500;
- line-height: 20px;
- text-decoration: none;
- position: relative;
- padding-bottom: 2px;
-
-
- &:before {
- content: '';
- position: absolute;
- left: 0;
- right: 100%;
- bottom: 0;
- height: 2px;
- background: #000;
- @include transition(all, .4s);
- }
-
- .vt-pinecone {
- color: $primary-color;
- font-size: 20px;
- }
-
- strong{
- font-weight: 500;
- color: #000;
- @include transition(all, .4s);
- }
-
- &.vigotech-dark {
- color: #eaeaea;
- strong{
- color: #fff;
- }
- }
-
- &:hover{
- strong {
- color: $primary-color;
- }
- &:before {
- right: 0;
- background: $primary-color;
- }
- }
-}
diff --git a/assets/_members.scss b/assets/_members.scss
deleted file mode 100644
index 92d2decc..00000000
--- a/assets/_members.scss
+++ /dev/null
@@ -1,39 +0,0 @@
-@include media($xs) {
- .vigotech-member-list {
- &.row {
- margin: 0;
- }
- }
-}
-
-
-
-.vigotech-member {
- .vigotech-next-event {
- i {
- @include fade-animation(1s);
- }
- }
-
- .logo-wrapper {
- text-align: center;
-
- .logo-content {
- display: inline-block;
- position: relative;
- }
- }
- .ivoox {
- transform: translate(0, 2px);
- }
-
-
-
- .vigotech-next-event {
- position: absolute;
- top: 0;
- left: 0;
- }
-}
-
-
diff --git a/assets/_menu.scss b/assets/_menu.scss
deleted file mode 100644
index d7b860b8..00000000
--- a/assets/_menu.scss
+++ /dev/null
@@ -1,51 +0,0 @@
-#menu {
- position: fixed;
- top: 10px;
- left: 30px;
-
- @media (max-width: 1800px) {
- display: none;
- }
-
-
- .logo {
- margin-bottom: 20px;
- display: block;
- width: 80px;
-
- svg {
-
- }
- }
- ul {
- list-style: none;
- margin: 0;
- padding: 0;
-
-
-
- li {
- margin-bottom: 7px;
- padding: 0;
- }
-
- a {
- font-size: 25px;
- text-transform: uppercase;
- color: $black;
- font-weight: 600;
- text-decoration: none;
- @include transition(all, .2s);
-
-
-
- &.active,
- &:hover {
- color: $primary-color;
- text-shadow: 2px 0 0 #fff, -2px 0 0 #fff, 0 2px 0 #fff, 0 -2px 0 #fff, 1px 1px #fff, -1px -1px 0 #fff, 1px -1px 0 #fff, -1px 1px 0 #fff;
- }
- &:hover {
- }
- }
- }
-}
diff --git a/assets/_mixins.scss b/assets/_mixins.scss
deleted file mode 100644
index b6771355..00000000
--- a/assets/_mixins.scss
+++ /dev/null
@@ -1,95 +0,0 @@
-@mixin media($devices) {
- @each $device in $devices {
- @media ($device) {
- @content;
- }
- }
-}
-
-@mixin transform($transform) {
- -ms-transform: $transform; /* IE 9 */
- -webkit-transform: $transform; /* Chrome, Safari, Opera */
- transform: $transform;
-}
-
-
-@mixin box-shadow($x: 0px, $y: 8px, $r: 3px, $color: #333) {
- -moz-box-shadow: $x $y $r $color;
- -webkit-box-shadow: $x $y $r $color;
- box-shadow: $x $y $r $color;
-}
-
-@mixin text-shadow($x: 0px, $y: 8px, $r: 3px, $color: #333) {
- -moz-text-shadow: $x $y $r $color;
- -webkit-text-shadow: $x $y $r $color;
- text-shadow: $x $y $r $color;
-}
-
-@mixin scale ($zoom: 1.1) {
- @include transform(scale($zoom));
-}
-
-@mixin rotate($angle: 90deg, $originX: 50%, $originY: 50%) {
- -webkit-transform: rotate($angle);
- -webkit-transform-origin: $originX $originY;
-
- -moz-transform: rotate($angle);
- -moz-transform-origin: $originX $originY;
-
- -o-transform: rotate($angle);
- -o-transform-origin: $originX $originY;
-
- -ms-transform: rotate($angle);
- -ms-transform-origin: $originX $originY;
-
- transform: rotate($angle);
- transform-origin: $originX $originY;
-}
-
-
-@mixin transition($property: all , $speed: 1s, $ease: ease-in-out) {
- -moz-transition: $property $speed $ease;
- -o-transition: $property $speed $ease;
- -webkit-transition: $property $speed $ease;
- transition: $property $speed $ease;
-}
-
-@mixin transition-delay($delay: 0.5s) {
- -webkit-transition-delay: $delay; /* Safari */
- transition-delay: $delay;
-}
-
-
-@mixin vertical-align($xs: true) {
- @if ($xs == false) {
- @include media(768px) {
- top: 50%;
- left: 0;
- right: 0;
- position: absolute;
- -webkit-transform: translateY(-50%);
- -ms-transform: translateY(-50%);
- transform: translateY(-50%);
- }
- } @else {
- top: 50%;
- position: absolute;
- left: 0;
- right: 0;
- -webkit-transform: translateY(-50%);
- -ms-transform: translateY(-50%);
- transform: translateY(-50%);
- }
-}
-
-
-@keyframes fade-animation {
- 0% { opacity:0.8; transform: scale(1)}
- 50% { opacity:1; transform: scale(1.2)}
- 100% { opacity:0.8; transform: scale(1)}
-}
-
-@mixin fade-animation($time: 1s) {
- animation: fade-animation $time infinite;
-
-}
diff --git a/assets/_post.scss b/assets/_post.scss
deleted file mode 100644
index d292424f..00000000
--- a/assets/_post.scss
+++ /dev/null
@@ -1,48 +0,0 @@
-#post {
- .post-content {
- font-size: 18px;
- hr {
- background: $primary-color;
- border: 0;
- height: 5px;
- margin-bottom: 20px;
- }
- padding-bottom: 40px;
- > * {
- margin-top: 0;
- }
- h1, h2, h3, h4, h5, h6 {
- margin: 30px 0 20px 0;
- }
-
- h1 {
- font-size: 30px;
- }
- p {
-
- line-height: 1em;
- margin-bottom: 1.2em;
- }
-
- ul, ol {
- margin-bottom: 20px;
- li {
- margin-bottom: 7px;
- }
- }
-
- a {
- color: $primary-color;
-
- &:hover {
- text-decoration: none;
- }
- }
-
- pre {
- background: rgba($primary-color, .2);
- padding: 15px;
- margin-bottom: 20px;
- }
- }
-}
diff --git a/assets/_variables.scss b/assets/_variables.scss
deleted file mode 100644
index f0cc00a6..00000000
--- a/assets/_variables.scss
+++ /dev/null
@@ -1,16 +0,0 @@
-$xs: "max-width: 767px" !default;
-$not-xs: "min-width: 768px" !default;
-$sm: "min-width: 768px) and (max-width: 991px" !default;
-$md: "min-width: 992px) and (max-width: 1199px" !default;
-$lg: "min-width: 1200px" !default;
-
-
-// Colors
-$primary-color: #e84a5f;
-$white: #fff;
-$black: #000;
-$gray: #22343A;
-$light-gray: #999;
-
-// Fonts
-$primary-font: Raleway;
diff --git a/assets/_videojs.scss b/assets/_videojs.scss
deleted file mode 100644
index 72a3b47d..00000000
--- a/assets/_videojs.scss
+++ /dev/null
@@ -1,3 +0,0 @@
-.video-js {
- width: 100%;
-}
diff --git a/assets/_videos.scss b/assets/_videos.scss
deleted file mode 100644
index 48e8c756..00000000
--- a/assets/_videos.scss
+++ /dev/null
@@ -1,74 +0,0 @@
-#videos {
- .anchor {
- display: block;
- position: relative;
- top: -130px;
- visibility: hidden;
- }
- .group-anchors {
- display: flex;
- margin-bottom: 50px;
- .group-anchor {
- display: flex;
- width: 60px;
- height: 60px;
- margin: 5px;
- align-items: center;
- justify-content: center;
- img {
- max-width: 100%;
- }
- }
- }
- .wrap {
- > .row {
- margin: 0;
- }
- }
-
- .group {
- margin-bottom: 60px;
- }
- .video {
- margin: 0 0 40px 0;
-
- iframe,
- .video-player-box,
- img {
- width: 100%;
- margin-bottom: 5px;
- }
-
- a {
- color: $black;
- text-decoration: none;
- display: block;
-
- &:hover {
- text-decoration: underline;
- }
- }
- h3 {
- margin-top: 7px;
- margin-bottom: 7px;
- }
- }
-
- .group-header {
- display: flex;
- border-bottom: 5px solid $primary-color;
- margin-bottom: 30px;
- padding-bottom: 5px;
- color: $black;
- align-items: center;
-
- .logo-wrapper {
- margin-right: 15px;
- width: 70px;
- position: relative;
- .member-logo {
- max-width: 100%;
- }
- }
- }
-}
diff --git a/assets/fonts/vigotech.eot b/assets/fonts/vigotech.eot
deleted file mode 100644
index 505dfe22..00000000
Binary files a/assets/fonts/vigotech.eot and /dev/null differ
diff --git a/assets/fonts/vigotech.svg b/assets/fonts/vigotech.svg
deleted file mode 100644
index e884d862..00000000
--- a/assets/fonts/vigotech.svg
+++ /dev/null
@@ -1,11 +0,0 @@
-
-
-
-Generated by IcoMoon
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/assets/fonts/vigotech.ttf b/assets/fonts/vigotech.ttf
deleted file mode 100644
index c14b2a62..00000000
Binary files a/assets/fonts/vigotech.ttf and /dev/null differ
diff --git a/assets/fonts/vigotech.woff b/assets/fonts/vigotech.woff
deleted file mode 100644
index 271b5727..00000000
Binary files a/assets/fonts/vigotech.woff and /dev/null differ
diff --git a/assets/i/ivoox.svg b/assets/i/ivoox.svg
deleted file mode 100644
index caed0d0b..00000000
--- a/assets/i/ivoox.svg
+++ /dev/null
@@ -1,10 +0,0 @@
-
-
-
-
-
diff --git a/assets/vigotech.scss b/assets/vigotech.scss
deleted file mode 100644
index 0ee2abbf..00000000
--- a/assets/vigotech.scss
+++ /dev/null
@@ -1,18 +0,0 @@
-@import
- "variables",
- "mixins",
- "layout",
- "footer",
- "elements",
- "cover",
- "menu",
- "members",
- "calendar",
- "post",
- "docs",
- "videojs",
- "videos",
- "friends",
- "made-with",
- "conversation"
-;
diff --git a/astro.config.mjs b/astro.config.mjs
new file mode 100644
index 00000000..99cbe41f
--- /dev/null
+++ b/astro.config.mjs
@@ -0,0 +1,27 @@
+// @ts-check
+import { defineConfig } from 'astro/config'
+import icon from 'astro-icon'
+
+import tailwindcss from '@tailwindcss/vite'
+
+/** @param {string | undefined} value */
+const normalizeBase = (value) => {
+ if (!value || value === '/') {
+ return '/'
+ }
+
+ return `/${String(value).replace(/^\/+|\/+$/g, '')}/`
+}
+
+// https://astro.build/config
+export default defineConfig({
+ site: process.env.SITE_URL || 'https://vigotech.org',
+ base: normalizeBase(process.env.PUBLIC_BASE_PATH),
+ integrations: [icon()],
+ vite: {
+ plugins: [tailwindcss()],
+ optimizeDeps: {
+ include: ['shaders/core'],
+ },
+ },
+})
diff --git a/commitlint.config.js b/commitlint.config.js
new file mode 100644
index 00000000..d179c690
--- /dev/null
+++ b/commitlint.config.js
@@ -0,0 +1,3 @@
+export default {
+ extends: ['@commitlint/config-conventional'],
+}
diff --git a/components/CalendarSection.vue b/components/CalendarSection.vue
deleted file mode 100644
index a56024f5..00000000
--- a/components/CalendarSection.vue
+++ /dev/null
@@ -1,47 +0,0 @@
-
-
-
-
-
diff --git a/components/ConversationSection.vue b/components/ConversationSection.vue
deleted file mode 100644
index 83f0a53f..00000000
--- a/components/ConversationSection.vue
+++ /dev/null
@@ -1,86 +0,0 @@
-
-
-
-
-
-
-
- Únete á conversa
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/components/CoverSection.vue b/components/CoverSection.vue
deleted file mode 100644
index 00a06ae3..00000000
--- a/components/CoverSection.vue
+++ /dev/null
@@ -1,87 +0,0 @@
-
-
-
-
-
-
-
-
- Vigo Tech Alliance
-
-
-
- Os grupos de tecnoloxía de Vigo facemos piña para promover a tecnoloxía na cidade
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/components/Friend.vue b/components/Friend.vue
deleted file mode 100644
index 9a893644..00000000
--- a/components/Friend.vue
+++ /dev/null
@@ -1,38 +0,0 @@
-
-
-
-
-
-
diff --git a/components/FriendsSection.vue b/components/FriendsSection.vue
deleted file mode 100644
index 0b85f2c0..00000000
--- a/components/FriendsSection.vue
+++ /dev/null
@@ -1,45 +0,0 @@
-
-
-
-
-
-
-
- Os nosos amigos
-
-
-
-
-
-
-
-
-
-
diff --git a/components/Menu.vue b/components/Menu.vue
deleted file mode 100644
index 0af740df..00000000
--- a/components/Menu.vue
+++ /dev/null
@@ -1,83 +0,0 @@
-
-
-
-
-
diff --git a/components/PageHeader.vue b/components/PageHeader.vue
deleted file mode 100644
index f1de79c1..00000000
--- a/components/PageHeader.vue
+++ /dev/null
@@ -1,36 +0,0 @@
-
-
-
-
-
diff --git a/components/VideosSection.vue b/components/VideosSection.vue
deleted file mode 100644
index 64abf997..00000000
--- a/components/VideosSection.vue
+++ /dev/null
@@ -1,68 +0,0 @@
-
-
-
-
-
-
-
- Charlas en vídeo
-
-
-
-
-
A maioría de charlas están gravadas e dispoñibles para o seu visionamento.
-
-
-
-
- Ver máis
-
-
-
-
-
-
-
-
-
diff --git a/components/VigotechCurrentEvents.vue b/components/VigotechCurrentEvents.vue
deleted file mode 100644
index 9c6204e0..00000000
--- a/components/VigotechCurrentEvents.vue
+++ /dev/null
@@ -1,54 +0,0 @@
-
-
-
-
- Evento activo
- Eventos en curso
-
-
-
-
-
-
-
diff --git a/components/VigotechDocsSection.vue b/components/VigotechDocsSection.vue
deleted file mode 100644
index 6081f902..00000000
--- a/components/VigotechDocsSection.vue
+++ /dev/null
@@ -1,64 +0,0 @@
-
-
-
-
-
-
-
- Documentos
-
-
-
-
-
-
-
-
-
-
-
diff --git a/components/VigotechMember.vue b/components/VigotechMember.vue
deleted file mode 100644
index 37a2f04c..00000000
--- a/components/VigotechMember.vue
+++ /dev/null
@@ -1,143 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
- {{ member.name }}
-
-
-
-
-
-
-
-
diff --git a/components/VigotechMemberList.vue b/components/VigotechMemberList.vue
deleted file mode 100644
index 281d0709..00000000
--- a/components/VigotechMemberList.vue
+++ /dev/null
@@ -1,32 +0,0 @@
-
-
-
-
-
diff --git a/components/VigotechMembersSection.vue b/components/VigotechMembersSection.vue
deleted file mode 100644
index a83b7dfc..00000000
--- a/components/VigotechMembersSection.vue
+++ /dev/null
@@ -1,42 +0,0 @@
-
-
-
-
-
-
diff --git a/components/VigotechNextEvent.vue b/components/VigotechNextEvent.vue
deleted file mode 100644
index efe0eb73..00000000
--- a/components/VigotechNextEvent.vue
+++ /dev/null
@@ -1,60 +0,0 @@
-
-
-
-
- Vindeiro evento
- Vindeiros eventos
-
-
-
-
-
-
-
diff --git a/components/VigotechNextEventTip.vue b/components/VigotechNextEventTip.vue
deleted file mode 100644
index d5d27a1f..00000000
--- a/components/VigotechNextEventTip.vue
+++ /dev/null
@@ -1,47 +0,0 @@
-
-
-
-
-
-
-
diff --git a/components/VigotechVideoPlayer.vue b/components/VigotechVideoPlayer.vue
deleted file mode 100644
index 2331ed6c..00000000
--- a/components/VigotechVideoPlayer.vue
+++ /dev/null
@@ -1,96 +0,0 @@
-
-
-
-
-
-
-
- {{ pubDate(video.pubDate) }}
- {{ video.title }}
-
-
-
-
-
-
-
{{ pubDate(video.pubDate) }}
- {{ video.title }}
-
-
-
-
-
diff --git a/config.json b/config.json
deleted file mode 100644
index 6aae3dab..00000000
--- a/config.json
+++ /dev/null
@@ -1,25 +0,0 @@
-{
- "social": [
- {
- "icon": "fa fa-twitter",
- "link": "https://twitter.com/vigotechallianc",
- "name": "Twitter"
- },
- {
- "icon": "fa fa-telegram",
- "link": "https://t.me/vigotech",
- "name": "Telegram"
- },
- {
- "icon": "fa fa-envelope-o",
- "link": "mailto:alliance@vigotech.org",
- "name": "Email alliance@vigotech.org"
- },
- {
- "icon": "fa fa-github",
- "link": "https://github.com/VigoTech",
- "name": "Github"
- }
-
- ]
-}
diff --git a/layouts/README.md b/layouts/README.md
deleted file mode 100644
index cad1ad57..00000000
--- a/layouts/README.md
+++ /dev/null
@@ -1,7 +0,0 @@
-# LAYOUTS
-
-**This directory is not required, you can delete it if you don't want to use it.**
-
-This directory contains your Application Layouts.
-
-More information about the usage of this directory in [the documentation](https://nuxtjs.org/guide/views#layouts).
diff --git a/layouts/default.vue b/layouts/default.vue
deleted file mode 100644
index 502ed986..00000000
--- a/layouts/default.vue
+++ /dev/null
@@ -1,83 +0,0 @@
-
-
-
-
-
-
-
-
- ×
-
-
-
- Empregamos cookies propias e de terceiros para mellorar a experiencia de usuario. Saber máis
-
-
-
- Non acepto
-
-
-
- Ok, adiante
-
-
-
-
-
-
diff --git a/lefthook.yml b/lefthook.yml
new file mode 100644
index 00000000..0c1ffce7
--- /dev/null
+++ b/lefthook.yml
@@ -0,0 +1,15 @@
+pre-commit:
+ commands:
+ lint:
+ run: pnpm lint
+ format:
+ run: pnpm format:check
+ type-check:
+ run: pnpm type-check
+ test:
+ run: pnpm test:coverage
+
+commit-msg:
+ commands:
+ commitlint:
+ run: pnpm commitlint --edit {1}
diff --git a/markdown/index.js b/markdown/index.js
deleted file mode 100644
index 570d2dfd..00000000
--- a/markdown/index.js
+++ /dev/null
@@ -1,17 +0,0 @@
-const fs = require('fs')
-const path = require('path')
-
-module.exports = {
- getSlugs (post, index) {
- let slug = post.substr(0, post.lastIndexOf('.md'));
- return `/post/${slug}`
- },
- getFiles () {
- let files = fs.readdirSync('./markdown');
- files = files.filter( file => {
- return path.extname(file).toLowerCase() === '.md';
- })
-
- return files
- }
-}
diff --git a/markdown/legal.md b/markdown/legal.md
deleted file mode 100644
index bc039bed..00000000
--- a/markdown/legal.md
+++ /dev/null
@@ -1,112 +0,0 @@
-A nosa web, como outras moitas, utiliza cookies que permitirán mellorar a súa experiencia como usuario e en cumprimento da LSSI (LEI 34/2002, do 11 de xullo, de servizos da sociedade da información e de comercio electrónico), imos informarlle sobre que son, cales utilizamos na nosa web, cómo eliminalas e pedirémoslle o consentimento para o seu uso.
-
-## INFORMACIÓN
-### Que son as cookies?
-
-Son pequenos arquivos de texto que se descargan e instalan no seu ordenador ou no seu móbil a través do seu navegador (Internet Explorer, Firefox, Chrome, Safari…) ou a través dunha aplicación Flash. As cookies permiten que as webs lle “lembren”, xa sexa durante unha visita (mediante as chamadas “cookies de sesión”) ou durante varias visitas (mediante as chamadas “cookies persistentes”) e almacenen información sobre as súas preferencias para ofrecerlle unha experiencia personalizada, máis fácil e máis rápida. Soamente o servidor que a instalou poderá ler o seu contido, que por outra banda, será anónimo. Aínda que se instalen no seu disco duro, ao ser só texto, non son capaces por si mesmas de acceder a información
-persoal do seu computador, nin a transmitir virus, tan só rastrexan a navegación sobre un sitio web. A continuación explicámoslle cales son as cookies segundo a súa función:
-
-## COOKIES SEGUNDO O PRAZO DE TEMPO
-
-### COOKIES DE SESIÓN
-Son cookies deseñadas para solicitar e almacenar datos mentres o usuario accede a unha páxina web. Adóitanse empregar para almacenar información que só interesa conservar para a prestación do servizo solicitado polo usuario nunha soa ocasión.
-
-### COOKIES PERSISTENTES
-Son un tipo de cookies no que os datos seguen almacenados no terminal e aos que se pode acceder e tratar durante un período definido polo responsable da cookie, e que pode ir duns minutos a varios anos.
-
-## COOKIES SEGUNDO A ENTIDADE QUE AS XESTIONE
-
-### COOKIES PROPIAS
-Son as creadas polo responsable da páxina web.
-
-### COOKIES DE TERCEIROS
-Son as creadas e xestionas por outras entidades, como prestadores de servizos publicitarios, de personalización ou análise, estes terceiros pódennos reportar datos anónimos.
-
-## COOKIES SEGUNDO FINALIDADE
-
-### COOKIES TÉCNICAS
-Son aquelas que permiten ao usuario a navegación a través dunha páxina web, plataforma ou aplicación e a utilización das diferentes opcións ou servizos que nela existan como, por exemplo, controlar o tráfico e a comunicación de datos, identificar a sesión, acceder a partes de acceso restrinxido, lembrar os elementos que integran un pedido, realizar o proceso de compra dun pedido, realizar a solicitude de inscrición ou participación nun evento, utilizar elementos de seguridade durante a navegación, almacenar contidos para a difusión de vídeos ou son ou compartir contidos a través de redes sociais.
-
-### COOKIES DE PERSONALIZACIÓN
-Son aquelas que permiten ao usuario acceder ao servizo con algunhas características de carácter xeral predefinidas en función dunha serie de criterios no terminal do usuario por exemplo serian o idioma, o tipo de navegador a través do cal accede ao servizo, a configuración rexional desde onde accede ao servizo, etc.
-
-### COOKIES DE ANÁLISE
-Son aquelas que permiten ao responsable das mesmas, o seguimento e análise do comportamento dos usuarios dos sitios web aos que están vinculadas. A información recollida mediante este tipo de cookies utilízase na medición da actividade dos sitios web, aplicación ou plataforma e para a elaboración de perfís de navegación dos usuarios dos devanditos sitios, aplicacións e plataformas, co fin de introducir melloras en función da análise dos datos de uso que fan os usuarios do servizo.
-
-### COOKIES PUBLICITARIAS
-Son aquelas que permiten a xestión, da forma máis eficaz posible, dos espazos publicitarios que, no seu caso, o editor incluíse nunha páxina web, aplicación ou plataforma desde a que presta o servizo solicitado en base a criterios como o contido editado ou a frecuencia na que se mostran os anuncios.
-
-
-### COOKIES DE PUBLICIDADE COMPORTAMENTAL
-Son aquelas que permiten a xestión, da forma máis eficaz posible, dos espazos publicitarios que, no seu caso, o editor incluíse nunha páxina web, aplicación ou plataforma desde a que presta o servizo solicitado. Estas cookies almacenan información do comportamento dos usuarios obtida a través da observación continuada dos seus hábitos de navegación, o que permite desenvolver un perfil específico para mostrar publicidade en función do mesmo.
-
-
-
-
-
-## Que tipo de cookies utilizamos?
-A continuación definímosche as funcións e o tipo de cookies que utilizamos en http://www.vigotech.org e a súa finalidade:
-
-
-
-### COOKIES PROPIAS
-
-### COOKIES DE TERCEIROS
-
-#### Google Analytics:
-
-Tipo: Cookie analítica de terceiros utilizadas por nós e por Google
-[Máis Información](https://developers.google.com/analytics/devguides/collection/analyticsjs):
-Definición: As cookies analíticas son aquelas que permiten ao responsable das mesmas, o seguimento e análise do comportamento dos usuarios dos sitios web aos que están vinculadas.
- Finalidade: A información recollida mediante este tipo de cookies utilízase na medición da actividade dos sitios web, aplicación ou plataforma e para a elaboración de perfís de navegación dos usuarios dos devanditos sitios, aplicacións e plataformas, co fin de introducir melloras en función da análise dos datos de uso que fan os usuarios do servizo.
-Cookies:
-_utma:
-Finalidade: Rexistra a data da primeira e última vez que o usuario visito o sitio web.
-Expira: 2 anos
-_utmb:
-Finalidade: Calcula o tempo que dura a visita dun usuario almacenando o momento que entro na páxina
-Expira: 30 minutos
-_utmc:
-Finalidade: Calcula o tempo que dura a visita dun usuario almacenando o momento que sae da páxina.
-Expira: Al finalizar la sesión
-_utmz:
-Finalidade: Mantén un seguimento de onde provén o visitante, que motor de procura utilizouse, en que ligazón fixo clic, que palabras craves utilizo e desde en que lugar do mundo accedeuse á páxina.
-Expira: 6 meses
-_ga.js:
-Finalidade: Cookies de orixe para: determinar o dominio que se medirá, distinguir aos usuarios únicos, lembrar o número e a duración das visitas anteriores, lembrar a información das fontes de tráfico, determinar o inicio e o fin dunha sesión, lembrar o valor das variables personalizadas de visitante.
-
-Expira: 2 anos
-_ga:
-Finalidade: Utilízase para distinguir aos usuarios
-Expira: 2 anos
-
-
-[TWITTER]
-
-
-## Revogación do consentimento
-Se máis adiante decides revogar o consentimento configurar o teu navegador para que rexeite as cookies e tamén deberás borrar o historial para eliminar as xa instaladas.
-
-Se por calquera motivo decides que non queres que se instalen as cookies no teu ordenador temos obriga de informarche sobre como facelo e para iso deberás configurar o teu navegador. A continuación facilitámosche as ligazóns para a configuración das cookies nos principais navegadores.
-
-## Desactivación das cookies.
-A continuación facilitámosche as ligazóns coa información necesaria para desactivar as cookies dos navegadores máis utilizados:
-
-Internet Explorer Más información
-Firefox Máis Información
-Chrome Máis información
-Opera Máis información
-Safari Máis información
-Safari para IOS Máis información
-Chrome para Android Máis Información
-Ligazóns: Cando enlaza con noticias ou vídeos externos á nosa web, a páxina enlazada pode conter outras cookies e deberá visitar a súa propia política de cookies para axustar a configuración, xa que son completamente alleas a nós.
-
-Se quere eliminar a publicidade orixinada polas cookies de terceira parte, tamén ten a opción de instalar no seu navegador un plugin como Adblock, que bloquee os anuncios.
-
-Tamén podes aplicar a extensión “Ghostery” ao seu navegador e bloquear individualmente aquelas cookies, plugins e widgets que non lle interesen.
-
-En calquera caso recomendamos facer unha limpeza do historial de navegación e das cookies do seu computador de maneira sistemática.
-
-Tamén podes obter máis información en: http://www.youronlinechoices.com/es/
-
-Por último, pode xestionar as cookies instaladas por Adobe Flash Player desde a web de Adobe. As cookies de terceiros poderán ser modificadas, implementadas ou anuladas por eles mesmos sen que nolo notifiquen, polo que non podemos facernos responsables de que a información estea perfectamente actualizada en todo momento segundo a lei establece. Con todo para ofrecerlle un mellor servizo de información enlazamos as políticas de cookies e privacidade destes terceiros coa finalidade de que se poidan consultar en calquera momento na súa versión máis actualizada e pola nosa banda iremos revisándoa periodicamente para actualizar os nosos textos.
\ No newline at end of file
diff --git a/markdown/test.md b/markdown/test.md
deleted file mode 100644
index 34b15989..00000000
--- a/markdown/test.md
+++ /dev/null
@@ -1,244 +0,0 @@
----
-__Advertisement :)__
-
-- __[pica](https://nodeca.github.io/pica/demo/)__ - high quality and fast image
- resize in browser.
-- __[babelfish](https://github.com/nodeca/babelfish/)__ - developer friendly
- i18n with plurals support and easy syntax.
-
-You will like those projects!
-
----
-
-# h1 Heading 8-)
-## h2 Heading
-### h3 Heading
-#### h4 Heading
-##### h5 Heading
-###### h6 Heading
-
-
-## Horizontal Rules
-
-___
-
----
-
-***
-
-
-## Typographic replacements
-
-Enable typographer option to see result.
-
-(c) (C) (r) (R) (tm) (TM) (p) (P) +-
-
-test.. test... test..... test?..... test!....
-
-!!!!!! ???? ,, -- ---
-
-"Smartypants, double quotes" and 'single quotes'
-
-
-## Emphasis
-
-**This is bold text**
-
-__This is bold text__
-
-*This is italic text*
-
-_This is italic text_
-
-~~Strikethrough~~
-
-
-## Blockquotes
-
-
-> Blockquotes can also be nested...
->> ...by using additional greater-than signs right next to each other...
-> > > ...or with spaces between arrows.
-
-
-## Lists
-
-Unordered
-
-+ Create a list by starting a line with `+`, `-`, or `*`
-+ Sub-lists are made by indenting 2 spaces:
- - Marker character change forces new list start:
- * Ac tristique libero volutpat at
- + Facilisis in pretium nisl aliquet
- - Nulla volutpat aliquam velit
-+ Very easy!
-
-Ordered
-
-1. Lorem ipsum dolor sit amet
-2. Consectetur adipiscing elit
-3. Integer molestie lorem at massa
-
-
-1. You can use sequential numbers...
-1. ...or keep all the numbers as `1.`
-
-Start numbering with offset:
-
-57. foo
-1. bar
-
-
-## Code
-
-Inline `code`
-
-Indented code
-
- // Some comments
- line 1 of code
- line 2 of code
- line 3 of code
-
-
-Block code "fences"
-
-```
-Sample text here...
-```
-
-Syntax highlighting
-
-``` js
-var foo = function (bar) {
- return bar++;
-};
-
-console.log(foo(5));
-```
-
-## Tables
-
-| Option | Description |
-| ------ | ----------- |
-| data | path to data files to supply the data that will be passed into templates. |
-| engine | engine to be used for processing templates. Handlebars is the default. |
-| ext | extension to be used for dest files. |
-
-Right aligned columns
-
-| Option | Description |
-| ------:| -----------:|
-| data | path to data files to supply the data that will be passed into templates. |
-| engine | engine to be used for processing templates. Handlebars is the default. |
-| ext | extension to be used for dest files. |
-
-
-## Links
-
-[link text](http://dev.nodeca.com)
-
-[link with title](http://nodeca.github.io/pica/demo/ "title text!")
-
-Autoconverted link https://github.com/nodeca/pica (enable linkify to see)
-
-
-## Images
-
-
-
-
-Like links, Images also have a footnote style syntax
-
-![Alt text][id]
-
-With a reference later in the document defining the URL location:
-
-[id]: https://octodex.github.com/images/dojocat.jpg "The Dojocat"
-
-
-## Plugins
-
-The killer feature of `markdown-it` is very effective support of
-[syntax plugins](https://www.npmjs.org/browse/keyword/markdown-it-plugin).
-
-
-### [Emojies](https://github.com/markdown-it/markdown-it-emoji)
-
-> Classic markup: :wink: :crush: :cry: :tear: :laughing: :yum:
->
-> Shortcuts (emoticons): :-) :-( 8-) ;)
-
-see [how to change output](https://github.com/markdown-it/markdown-it-emoji#change-output) with twemoji.
-
-
-### [Subscript](https://github.com/markdown-it/markdown-it-sub) / [Superscript](https://github.com/markdown-it/markdown-it-sup)
-
-- 19^th^
-- H~2~O
-
-
-### [\](https://github.com/markdown-it/markdown-it-ins)
-
-++Inserted text++
-
-### [\](https://github.com/markdown-it/markdown-it-mark)
-
-==Marked text==
-
-
-### [Footnotes](https://github.com/markdown-it/markdown-it-footnote)
-
-Footnote 1 link[^first].
-
-Footnote 2 link[^second].
-
-Inline footnote^[Text of inline footnote] definition.
-
-Duplicated footnote reference[^second].
-
-[^first]: Footnote **can have markup**
-
- and multiple paragraphs.
-
-[^second]: Footnote text.
-
-
-### [Definition lists](https://github.com/markdown-it/markdown-it-deflist)
-
-Term 1
-
-: Definition 1
-with lazy continuation.
-
-Term 2 with *inline markup*
-
-: Definition 2
-
- { some code, part of Definition 2 }
-
- Third paragraph of definition 2.
-
-_Compact style:_
-
-Term 1
- ~ Definition 1
-
-Term 2
- ~ Definition 2a
- ~ Definition 2b
-
-
-### [Abbreviations](https://github.com/markdown-it/markdown-it-abbr)
-
-This is HTML abbreviation example.
-
-It converts "HTML", but keep intact partial entries like "xxxHTMLyyy" and so on.
-
-*[HTML]: Hyper Text Markup Language
-
-### [Custom containers](https://github.com/markdown-it/markdown-it-container)
-
-::: warning
-*here be dragons*
-:::
diff --git a/middleware/README.md b/middleware/README.md
deleted file mode 100644
index 009e48c5..00000000
--- a/middleware/README.md
+++ /dev/null
@@ -1,8 +0,0 @@
-# MIDDLEWARE
-
-**This directory is not required, you can delete it if you don't want to use it.**
-
-This directory contains your application middleware.
-The middleware lets you define custom function to be ran before rendering a page or a group of pages (layouts).
-
-More information about the usage of this directory in [the documentation](https://nuxtjs.org/guide/routing#middleware).
diff --git a/nuxt.config.js b/nuxt.config.js
deleted file mode 100644
index fca65c8b..00000000
--- a/nuxt.config.js
+++ /dev/null
@@ -1,122 +0,0 @@
-const pkg = require('./package')
-require('dotenv').config()
-const markdown = require('./markdown')
-
-const markdownFiles = markdown.getFiles()
-
-
-const routerBase = process.env.DEPLOY_ENV === 'GH_PAGES' ? {
- router: {
- base: '/',
- baseUrl: 'https://vigotech.org/'
- }
-} : {
- router: {
- base: '/',
- }
-}
-
-module.exports = {
- ...routerBase,
- mode: 'universal',
- env: {
- 'VIGOTECH_MEMBERS_SOURCE': '/vigotech.json',
- 'VIGOTECH_MEMBERS_SOURCE_FILE': 'static/vigotech.json',
- 'VIGOTECH_MEMBERS_SOURCE_GENERATED': '/vigotech-generated.json',
- 'VIGOTECH_MEMBERS_SOURCE_GENERATED_FILE': 'static/vigotech-generated.json',
- 'MEETUP_API_BASE': 'http://api.meetup.com'
- },
- /*
- ** Headers of the page
- */
- head: {
- title: 'VigoTech Alliance',
- meta: [
- { charset: 'utf-8' },
- { name: 'viewport', content: 'width=device-width, initial-scale=1' },
- { hid: 'description', name: 'description', content: pkg.description }
- ],
- link: [
- { rel: 'icon', type: 'image/x-icon', href: '/favicon.ico' }
- ],
- bodyAttrs: {
- class: 'layout'
- }
- },
-
- /*
- ** Customize the progress-bar color
- */
- loading: { color: '#e84a5f' },
-
- /*
- ** Global CSS
- */
- css: [
- 'assets/vigotech.scss',
- 'font-awesome/css/font-awesome.css',
- 'flexboxgrid/css/flexboxgrid.css',
- 'video.js/dist/video-js.css'
- ],
-
- /*
- ** Plugins to load before mounting the App
- */
- plugins: [
- { src: '~/plugins/scrollTo.js', ssr: false },
- { src: '~/plugins/scrollactive.js', ssr: false },
- { src: '~/plugins/sticky.js', ssr: false },
- { src: '~/plugins/moment.js'},
- { src: '~/plugins/localStorage.js', ssr: false },
- { src: '~/plugins/nuxt-video-player-plugin.js', ssr: false },
- { src: '~/plugins/cookies.js', ssr: false },
- { src: '~/plugins/ga.js', ssr: false }
- ],
-
- /*
- ** Nuxt.js modules
- */
- modules: [
- '@nuxtjs/dotenv',
- '@nuxtjs/axios',
- '@nuxtjs/proxy',
- ['@nuxtjs/markdownit', { linkify: true } ]
- ],
- /*
- ** Generate
- */
- generate: {
- routes: function() {
- const mdRoutes = markdownFiles.map(markdown.getSlugs)
- return mdRoutes
- }
- },
- /*
- ** Axios module configuration
- */
- axios: {
- // See https://github.com/nuxt-community/axios-module#options
- baseURL: routerBase.router.baseUrl,
- browserBaseURL: routerBase.router.baseUrl
- },
- /*
- ** Build configuration
- */
- build: {
- /*
- ** You can extend webpack config here
- */
- extractCSS: true,
- extend(config, ctx) {
- // Run ESLint on save
- if (ctx.isDev && ctx.isClient) {
- config.module.rules.push({
- enforce: 'pre',
- test: /\.(js|vue)$/,
- loader: 'eslint-loader',
- exclude: /(node_modules)/
- })
- }
- }
- }
-}
diff --git a/package.json b/package.json
index 4e48c6b0..e775cf64 100644
--- a/package.json
+++ b/package.json
@@ -1,62 +1,52 @@
{
- "name": "vigotech.github.io-nuxt",
- "version": "1.0.0",
- "description": "VigoTech Alliance Website",
- "author": "Sergio Carracedo",
- "private": true,
+ "name": "website",
+ "version": "0.0.1",
+ "type": "module",
"scripts": {
- "dev": "nuxt",
- "build": "nuxt build",
- "start": "nuxt start",
- "generate": "nuxt generate",
- "lint": "eslint --ext .js,.vue --ignore-path .gitignore .",
- "precommit": "npm run lint",
- "prepare-json": "node prepare-json.js",
- "build:gh-pages": "DEPLOY_ENV=GH_PAGES nuxt build",
- "generate:gh-pages": "DEPLOY_ENV=GH_PAGES nuxt generate"
+ "dev": "node scripts/dev.mjs",
+ "generate:data": "node scripts/generate-vigotech-json.mjs",
+ "build": "astro check && astro build",
+ "preview": "astro preview",
+ "astro": "astro",
+ "check": "astro check",
+ "test": "vitest",
+ "test:ui": "vitest --ui",
+ "test:coverage": "vitest run --coverage",
+ "test:e2e": "playwright test",
+ "lint": "oxlint",
+ "format": "oxfmt",
+ "format:check": "oxfmt --check",
+ "type-check": "tsc --noEmit",
+ "prepare": "lefthook install"
},
"dependencies": {
- "@nuxtjs/axios": "^5.0.0",
- "@nuxtjs/markdownit": "^2.0.0",
- "@nuxtjs/proxy": "^2.1.0",
- "axios": "0.21.1",
- "cross-env": "^7.0.3",
- "eslint-utils": "^3.0.0",
- "flexboxgrid": "^6.3.1",
- "font-awesome": "^4.7.0",
- "lodash": "^4.17.19",
- "lodash.template": "^4.5.0",
- "mixin-deep": "^2.0.1",
- "moment": "^2.22.2",
- "nuxt": "^2.15.6",
- "serialize-javascript": "^5.0.1",
- "set-value": "^4.0.0",
- "vue-analytics": "^5.16.2",
- "vue-cookie-accept-decline": "^5.1.0",
- "vue-moment": "^4.0.0",
- "vue-scrollactive": "^0.9.3",
- "vue-scrollto": "^2.13.0",
- "vue-sticky": "^3.3.4",
- "vue-video-player": "^5.0.2",
- "vuex": "^3.0.1",
- "vuex-persistedstate": "^2.5.4"
+ "@iconify-json/lucide": "^1.2.98",
+ "@tailwindcss/vite": "^4.2.2",
+ "astro": "^6.0.8",
+ "astro-icon": "^1.1.5",
+ "metagroup-schema-tools": "^1.1.0",
+ "shaders": "^2.4.78",
+ "tailwindcss": "^4.2.2"
},
"devDependencies": {
- "@nuxtjs/dotenv": "^1.3.0",
- "babel-eslint": "^10.1.0",
- "colors": "^1.3.2",
- "eslint": "^7.27.0",
- "eslint-loader": "^4.0.2",
- "eslint-plugin-vue": "^7.10.0",
- "google-auth-library": "^7.1.0",
- "googleapis": "^74.2.0",
- "jsonschema": "^1.2.4",
- "metagroup-schema-tools": "^1.0.8",
- "node-sass": "^6.0.0",
- "nodemon": "^2.0.7",
- "rss-parser": "^3.5.2",
- "sass-loader": "^10.2.0",
- "sync-request": "^6.0.0",
- "url-loader": "^4.1.1"
+ "@astrojs/check": "^0.9.8",
+ "@commitlint/cli": "^20.5.0",
+ "@commitlint/config-conventional": "^20.5.0",
+ "@playwright/test": "^1.58.2",
+ "@testing-library/jest-dom": "^6.9.1",
+ "@types/node": "^25.5.0",
+ "@vitest/coverage-v8": "^4.1.1",
+ "@vitest/ui": "^4.1.1",
+ "autoprefixer": "^10.4.27",
+ "jsdom": "^29.0.1",
+ "lefthook": "^2.1.4",
+ "oxfmt": "^0.41.0",
+ "oxlint": "^1.56.0",
+ "postcss": "^8.5.8",
+ "typescript": "^5.9.3",
+ "vitest": "^4.1.1"
+ },
+ "engines": {
+ "node": ">=22.12.0"
}
}
diff --git a/pages/README.md b/pages/README.md
deleted file mode 100644
index 7a6cffa6..00000000
--- a/pages/README.md
+++ /dev/null
@@ -1,6 +0,0 @@
-# PAGES
-
-This directory contains your Application Views and Routes.
-The framework reads all the `*.vue` files inside this directory and create the router of your application.
-
-More information about the usage of this directory in [the documentation](https://nuxtjs.org/guide/routing).
diff --git a/pages/index.vue b/pages/index.vue
deleted file mode 100644
index 609c66dd..00000000
--- a/pages/index.vue
+++ /dev/null
@@ -1,91 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/pages/post/_slug.vue b/pages/post/_slug.vue
deleted file mode 100644
index f2d432e6..00000000
--- a/pages/post/_slug.vue
+++ /dev/null
@@ -1,36 +0,0 @@
-
-
-
-
-
-
diff --git a/pages/videos.vue b/pages/videos.vue
deleted file mode 100644
index 38768119..00000000
--- a/pages/videos.vue
+++ /dev/null
@@ -1,128 +0,0 @@
-
-
-
-
-
diff --git a/playwright.config.ts b/playwright.config.ts
new file mode 100644
index 00000000..b0a4649c
--- /dev/null
+++ b/playwright.config.ts
@@ -0,0 +1,26 @@
+import { defineConfig, devices } from '@playwright/test'
+
+export default defineConfig({
+ testDir: './playwright',
+ fullyParallel: true,
+ forbidOnly: !!process.env.CI,
+ retries: process.env.CI ? 2 : 0,
+ workers: process.env.CI ? 1 : undefined,
+ reporter: 'html',
+ use: {
+ baseURL: 'http://127.0.0.1:4321',
+ trace: 'on-first-retry',
+ },
+ projects: [
+ {
+ name: 'chromium',
+ use: { ...devices['Desktop Chrome'] },
+ },
+ ],
+ webServer: {
+ command: 'pnpm preview',
+ url: 'http://127.0.0.1:4321',
+ reuseExistingServer: !process.env.CI,
+ timeout: 120_000,
+ },
+})
diff --git a/playwright/home.spec.ts b/playwright/home.spec.ts
new file mode 100644
index 00000000..5b04bf6f
--- /dev/null
+++ b/playwright/home.spec.ts
@@ -0,0 +1,6 @@
+import { expect, test } from '@playwright/test'
+
+test('homepage title renders', async ({ page }) => {
+ await page.goto('/')
+ await expect(page).toHaveTitle('Astro')
+})
diff --git a/plugins/README.md b/plugins/README.md
deleted file mode 100644
index 0d227f3f..00000000
--- a/plugins/README.md
+++ /dev/null
@@ -1,7 +0,0 @@
-# PLUGINS
-
-**This directory is not required, you can delete it if you don't want to use it.**
-
-This directory contains your Javascript plugins that you want to run before mounting the root Vue.js application.
-
-More information about the usage of this directory in [the documentation](https://nuxtjs.org/guide/plugins).
diff --git a/plugins/cookies.js b/plugins/cookies.js
deleted file mode 100644
index b5c813a1..00000000
--- a/plugins/cookies.js
+++ /dev/null
@@ -1,5 +0,0 @@
-import Vue from 'vue';
-import VueCookieAcceptDecline from 'vue-cookie-accept-decline';
-import 'vue-cookie-accept-decline/dist/vue-cookie-accept-decline.css';
-
-Vue.component('vue-cookie-accept-decline', VueCookieAcceptDecline);
\ No newline at end of file
diff --git a/plugins/ga.js b/plugins/ga.js
deleted file mode 100644
index d62fd8b4..00000000
--- a/plugins/ga.js
+++ /dev/null
@@ -1,7 +0,0 @@
-import Vue from 'vue'
-import VueAnalytics from 'vue-analytics'
-
-Vue.use(VueAnalytics, {
- id: 'UA-98368785-1', //process.env.GA,
- disabled: true
-})
\ No newline at end of file
diff --git a/plugins/localStorage.js b/plugins/localStorage.js
deleted file mode 100644
index 0dd9857c..00000000
--- a/plugins/localStorage.js
+++ /dev/null
@@ -1,7 +0,0 @@
-// import createPersistedState from 'vuex-persistedstate'
-
-// export default ({store}) => {
-// createPersistedState({
-// key: 'vigotech'
-// })(store)
-// }
diff --git a/plugins/moment.js b/plugins/moment.js
deleted file mode 100644
index d18fda26..00000000
--- a/plugins/moment.js
+++ /dev/null
@@ -1,8 +0,0 @@
-import Vue from 'vue'
-import moment from 'moment'
-import VueMoment from 'vue-moment'
-moment.locale('gl')
-
-Vue.use(VueMoment, {
- moment
-})
diff --git a/plugins/nuxt-video-player-plugin.js b/plugins/nuxt-video-player-plugin.js
deleted file mode 100644
index ac46b860..00000000
--- a/plugins/nuxt-video-player-plugin.js
+++ /dev/null
@@ -1,9 +0,0 @@
-import Vue from 'vue'
-
-// const VueVideoPlayer = require('vue-video-player/dist/ssr')
-// Vue.use(VueVideoPlayer)
-
-if (process.browser) {
- const VueVideoPlayer = require('vue-video-player/dist/ssr')
- Vue.use(VueVideoPlayer)
-}
diff --git a/plugins/scrollTo.js b/plugins/scrollTo.js
deleted file mode 100644
index 58e8dea4..00000000
--- a/plugins/scrollTo.js
+++ /dev/null
@@ -1,14 +0,0 @@
-import Vue from 'vue'
-import VueScrollTo from 'vue-scrollto'
-
-Vue.use(VueScrollTo, {
- container: 'body',
- duration: 500,
- easing: 'ease',
- offset: 0,
- cancelable: true,
- onDone: false,
- onCancel: false,
- x: false,
- y: true
-})
diff --git a/plugins/scrollactive.js b/plugins/scrollactive.js
deleted file mode 100644
index 1bdd501a..00000000
--- a/plugins/scrollactive.js
+++ /dev/null
@@ -1,4 +0,0 @@
-import Vue from 'vue'
-import VueScrollactive from 'vue-scrollactive'
-
-Vue.use(VueScrollactive)
diff --git a/plugins/sticky.js b/plugins/sticky.js
deleted file mode 100644
index 7a36ae3f..00000000
--- a/plugins/sticky.js
+++ /dev/null
@@ -1,4 +0,0 @@
-import Vue from 'vue'
-import VueSticky from 'vue-sticky'
-
-Vue.directive('sticky', VueSticky)
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
new file mode 100644
index 00000000..31643fad
--- /dev/null
+++ b/pnpm-lock.yaml
@@ -0,0 +1,6732 @@
+lockfileVersion: '9.0'
+
+settings:
+ autoInstallPeers: true
+ excludeLinksFromLockfile: false
+
+importers:
+
+ .:
+ dependencies:
+ '@iconify-json/lucide':
+ specifier: ^1.2.98
+ version: 1.2.98
+ '@tailwindcss/vite':
+ specifier: ^4.2.2
+ version: 4.2.2(vite@7.3.1(@types/node@25.5.0)(jiti@2.6.1)(lightningcss@1.32.0)(yaml@2.8.3))
+ astro:
+ specifier: ^6.0.8
+ version: 6.0.8(@types/node@25.5.0)(jiti@2.6.1)(lightningcss@1.32.0)(rollup@4.60.0)(typescript@5.9.3)(yaml@2.8.3)
+ astro-icon:
+ specifier: ^1.1.5
+ version: 1.1.5
+ metagroup-schema-tools:
+ specifier: ^1.1.0
+ version: 1.1.0
+ shaders:
+ specifier: ^2.4.78
+ version: 2.4.78(react-dom@19.2.4(react@19.2.4))(react@19.2.4)
+ tailwindcss:
+ specifier: ^4.2.2
+ version: 4.2.2
+ devDependencies:
+ '@astrojs/check':
+ specifier: ^0.9.8
+ version: 0.9.8(prettier@3.8.1)(typescript@5.9.3)
+ '@commitlint/cli':
+ specifier: ^20.5.0
+ version: 20.5.0(@types/node@25.5.0)(conventional-commits-parser@6.3.0)(typescript@5.9.3)
+ '@commitlint/config-conventional':
+ specifier: ^20.5.0
+ version: 20.5.0
+ '@playwright/test':
+ specifier: ^1.58.2
+ version: 1.58.2
+ '@testing-library/jest-dom':
+ specifier: ^6.9.1
+ version: 6.9.1
+ '@types/node':
+ specifier: ^25.5.0
+ version: 25.5.0
+ '@vitest/coverage-v8':
+ specifier: ^4.1.1
+ version: 4.1.1(vitest@4.1.1)
+ '@vitest/ui':
+ specifier: ^4.1.1
+ version: 4.1.1(vitest@4.1.1)
+ autoprefixer:
+ specifier: ^10.4.27
+ version: 10.4.27(postcss@8.5.8)
+ jsdom:
+ specifier: ^29.0.1
+ version: 29.0.1
+ lefthook:
+ specifier: ^2.1.4
+ version: 2.1.4
+ oxfmt:
+ specifier: ^0.41.0
+ version: 0.41.0
+ oxlint:
+ specifier: ^1.56.0
+ version: 1.56.0
+ postcss:
+ specifier: ^8.5.8
+ version: 8.5.8
+ typescript:
+ specifier: ^5.9.3
+ version: 5.9.3
+ vitest:
+ specifier: ^4.1.1
+ version: 4.1.1(@types/node@25.5.0)(@vitest/ui@4.1.1)(jsdom@29.0.1)(vite@7.3.1(@types/node@25.5.0)(jiti@2.6.1)(lightningcss@1.32.0)(yaml@2.8.3))
+
+packages:
+
+ '@adobe/css-tools@4.4.4':
+ resolution: {integrity: sha512-Elp+iwUx5rN5+Y8xLt5/GRoG20WGoDCQ/1Fb+1LiGtvwbDavuSk0jhD/eZdckHAuzcDzccnkv+rEjyWfRx18gg==}
+
+ '@antfu/install-pkg@1.1.0':
+ resolution: {integrity: sha512-MGQsmw10ZyI+EJo45CdSER4zEb+p31LpDAFp2Z3gkSd1yqVZGi0Ebx++YTEMonJy4oChEMLsxZ64j8FH6sSqtQ==}
+
+ '@antfu/utils@8.1.1':
+ resolution: {integrity: sha512-Mex9nXf9vR6AhcXmMrlz/HVgYYZpVGJ6YlPgwl7UnaFpnshXs6EK/oa5Gpf3CzENMjkvEx2tQtntGnb7UtSTOQ==}
+
+ '@asamuzakjp/css-color@5.0.1':
+ resolution: {integrity: sha512-2SZFvqMyvboVV1d15lMf7XiI3m7SDqXUuKaTymJYLN6dSGadqp+fVojqJlVoMlbZnlTmu3S0TLwLTJpvBMO1Aw==}
+ engines: {node: ^20.19.0 || ^22.12.0 || >=24.0.0}
+
+ '@asamuzakjp/dom-selector@7.0.4':
+ resolution: {integrity: sha512-jXR6x4AcT3eIrS2fSNAwJpwirOkGcd+E7F7CP3zjdTqz9B/2huHOL8YJZBgekKwLML+u7qB/6P1LXQuMScsx0w==}
+ engines: {node: ^20.19.0 || ^22.12.0 || >=24.0.0}
+
+ '@asamuzakjp/nwsapi@2.3.9':
+ resolution: {integrity: sha512-n8GuYSrI9bF7FFZ/SjhwevlHc8xaVlb/7HmHelnc/PZXBD2ZR49NnN9sMMuDdEGPeeRQ5d0hqlSlEpgCX3Wl0Q==}
+
+ '@astrojs/check@0.9.8':
+ resolution: {integrity: sha512-LDng8446QLS5ToKjRHd3bgUdirvemVVExV7nRyJfW2wV36xuv7vDxwy5NWN9zqeSEDgg0Tv84sP+T3yEq+Zlkw==}
+ hasBin: true
+ peerDependencies:
+ typescript: ^5.0.0
+
+ '@astrojs/compiler@2.13.1':
+ resolution: {integrity: sha512-f3FN83d2G/v32ipNClRKgYv30onQlMZX1vCeZMjPsMMPl1mDpmbl0+N5BYo4S/ofzqJyS5hvwacEo0CCVDn/Qg==}
+
+ '@astrojs/compiler@3.0.1':
+ resolution: {integrity: sha512-z97oYbdebO5aoWzuJ/8q5hLK232+17KcLZ7cJ8BCWk6+qNzVxn/gftC0KzMBUTD8WAaBkPpNSQK6PXLnNrZ0CA==}
+
+ '@astrojs/internal-helpers@0.8.0':
+ resolution: {integrity: sha512-J56GrhEiV+4dmrGLPNOl2pZjpHXAndWVyiVDYGDuw6MWKpBSEMLdFxHzeM/6sqaknw9M+HFfHZAcvi3OfT3D/w==}
+
+ '@astrojs/language-server@2.16.6':
+ resolution: {integrity: sha512-N990lu+HSFiG57owR0XBkr02BYMgiLCshLf+4QG4v6jjSWkBeQGnzqi+E1L08xFPPJ7eEeXnxPXGLaVv5pa4Ug==}
+ hasBin: true
+ peerDependencies:
+ prettier: ^3.0.0
+ prettier-plugin-astro: '>=0.11.0'
+ peerDependenciesMeta:
+ prettier:
+ optional: true
+ prettier-plugin-astro:
+ optional: true
+
+ '@astrojs/markdown-remark@7.0.1':
+ resolution: {integrity: sha512-zAfLJmn07u9SlDNNHTpjv0RT4F8D4k54NR7ReRas8CO4OeGoqSvOuKwqCFg2/cqN3wHwdWlK/7Yv/lMXlhVIaw==}
+
+ '@astrojs/prism@4.0.1':
+ resolution: {integrity: sha512-nksZQVjlferuWzhPsBpQ1JE5XuKAf1id1/9Hj4a9KG4+ofrlzxUUwX4YGQF/SuDiuiGKEnzopGOt38F3AnVWsQ==}
+ engines: {node: '>=22.12.0'}
+
+ '@astrojs/telemetry@3.3.0':
+ resolution: {integrity: sha512-UFBgfeldP06qu6khs/yY+q1cDAaArM2/7AEIqQ9Cuvf7B1hNLq0xDrZkct+QoIGyjq56y8IaE2I3CTvG99mlhQ==}
+ engines: {node: 18.20.8 || ^20.3.0 || >=22.0.0}
+
+ '@astrojs/yaml2ts@0.2.3':
+ resolution: {integrity: sha512-PJzRmgQzUxI2uwpdX2lXSHtP4G8ocp24/t+bZyf5Fy0SZLSF9f9KXZoMlFM/XCGue+B0nH/2IZ7FpBYQATBsCg==}
+
+ '@babel/code-frame@7.29.0':
+ resolution: {integrity: sha512-9NhCeYjq9+3uxgdtp20LSiJXJvN0FeCtNGpJxuMFZ1Kv3cWUNb6DOhJwUvcVCzKGR66cw4njwM6hrJLqgOwbcw==}
+ engines: {node: '>=6.9.0'}
+
+ '@babel/helper-string-parser@7.27.1':
+ resolution: {integrity: sha512-qMlSxKbpRlAridDExk92nSobyDdpPijUq2DW6oDnUqd0iOGxmQjyqhMIihI9+zv4LPyZdRje2cavWPbCbWm3eA==}
+ engines: {node: '>=6.9.0'}
+
+ '@babel/helper-validator-identifier@7.28.5':
+ resolution: {integrity: sha512-qSs4ifwzKJSV39ucNjsvc6WVHs6b7S03sOh2OcHF9UHfVPqWWALUsNUVzhSBiItjRZoLHx7nIarVjqKVusUZ1Q==}
+ engines: {node: '>=6.9.0'}
+
+ '@babel/parser@7.29.2':
+ resolution: {integrity: sha512-4GgRzy/+fsBa72/RZVJmGKPmZu9Byn8o4MoLpmNe1m8ZfYnz5emHLQz3U4gLud6Zwl0RZIcgiLD7Uq7ySFuDLA==}
+ engines: {node: '>=6.0.0'}
+ hasBin: true
+
+ '@babel/types@7.29.0':
+ resolution: {integrity: sha512-LwdZHpScM4Qz8Xw2iKSzS+cfglZzJGvofQICy7W7v4caru4EaAmyUuO6BGrbyQ2mYV11W0U8j5mBhd14dd3B0A==}
+ engines: {node: '>=6.9.0'}
+
+ '@bcoe/v8-coverage@1.0.2':
+ resolution: {integrity: sha512-6zABk/ECA/QYSCQ1NGiVwwbQerUCZ+TQbp64Q3AgmfNvurHH0j8TtXa1qbShXA6qqkpAj4V5W8pP6mLe1mcMqA==}
+ engines: {node: '>=18'}
+
+ '@bramus/specificity@2.4.2':
+ resolution: {integrity: sha512-ctxtJ/eA+t+6q2++vj5j7FYX3nRu311q1wfYH3xjlLOsczhlhxAg2FWNUXhpGvAw3BWo1xBcvOV6/YLc2r5FJw==}
+ hasBin: true
+
+ '@capsizecss/unpack@4.0.0':
+ resolution: {integrity: sha512-VERIM64vtTP1C4mxQ5thVT9fK0apjPFobqybMtA1UdUujWka24ERHbRHFGmpbbhp73MhV+KSsHQH9C6uOTdEQA==}
+ engines: {node: '>=18'}
+
+ '@clack/core@1.1.0':
+ resolution: {integrity: sha512-SVcm4Dqm2ukn64/8Gub2wnlA5nS2iWJyCkdNHcvNHPIeBTGojpdJ+9cZKwLfmqy7irD4N5qLteSilJlE0WLAtA==}
+
+ '@clack/prompts@1.1.0':
+ resolution: {integrity: sha512-pkqbPGtohJAvm4Dphs2M8xE29ggupihHdy1x84HNojZuMtFsHiUlRvqD24tM2+XmI+61LlfNceM3Wr7U5QES5g==}
+
+ '@commitlint/cli@20.5.0':
+ resolution: {integrity: sha512-yNkyN/tuKTJS3wdVfsZ2tXDM4G4Gi7z+jW54Cki8N8tZqwKBltbIvUUrSbT4hz1bhW/h0CdR+5sCSpXD+wMKaQ==}
+ engines: {node: '>=v18'}
+ hasBin: true
+
+ '@commitlint/config-conventional@20.5.0':
+ resolution: {integrity: sha512-t3Ni88rFw1XMa4nZHgOKJ8fIAT9M2j5TnKyTqJzsxea7FUetlNdYFus9dz+MhIRZmc16P0PPyEfh6X2d/qw8SA==}
+ engines: {node: '>=v18'}
+
+ '@commitlint/config-validator@20.5.0':
+ resolution: {integrity: sha512-T/Uh6iJUzyx7j35GmHWdIiGRQB+ouZDk0pwAaYq4SXgB54KZhFdJ0vYmxiW6AMYICTIWuyMxDBl1jK74oFp/Gw==}
+ engines: {node: '>=v18'}
+
+ '@commitlint/ensure@20.5.0':
+ resolution: {integrity: sha512-IpHqAUesBeW1EDDdjzJeaOxU9tnogLAyXLRBn03SHlj1SGENn2JGZqSWGkFvBJkJzfXAuCNtsoYzax+ZPS+puw==}
+ engines: {node: '>=v18'}
+
+ '@commitlint/execute-rule@20.0.0':
+ resolution: {integrity: sha512-xyCoOShoPuPL44gVa+5EdZsBVao/pNzpQhkzq3RdtlFdKZtjWcLlUFQHSWBuhk5utKYykeJPSz2i8ABHQA+ZZw==}
+ engines: {node: '>=v18'}
+
+ '@commitlint/format@20.5.0':
+ resolution: {integrity: sha512-TI9EwFU/qZWSK7a5qyXMpKPPv3qta7FO4tKW+Wt2al7sgMbLWTsAcDpX1cU8k16TRdsiiet9aOw0zpvRXNJu7Q==}
+ engines: {node: '>=v18'}
+
+ '@commitlint/is-ignored@20.5.0':
+ resolution: {integrity: sha512-JWLarAsurHJhPozbuAH6GbP4p/hdOCoqS9zJMfqwswne+/GPs5V0+rrsfOkP68Y8PSLphwtFXV0EzJ+GTXTTGg==}
+ engines: {node: '>=v18'}
+
+ '@commitlint/lint@20.5.0':
+ resolution: {integrity: sha512-jiM3hNUdu04jFBf1VgPdjtIPvbuVfDTBAc6L98AWcoLjF5sYqkulBHBzlVWll4rMF1T5zeQFB6r//a+s+BBKlA==}
+ engines: {node: '>=v18'}
+
+ '@commitlint/load@20.5.0':
+ resolution: {integrity: sha512-sLhhYTL/KxeOTZjjabKDhwidGZan84XKK1+XFkwDYL/4883kIajcz/dZFAhBJmZPtL8+nBx6bnkzA95YxPeDPw==}
+ engines: {node: '>=v18'}
+
+ '@commitlint/message@20.4.3':
+ resolution: {integrity: sha512-6akwCYrzcrFcTYz9GyUaWlhisY4lmQ3KvrnabmhoeAV8nRH4dXJAh4+EUQ3uArtxxKQkvxJS78hNX2EU3USgxQ==}
+ engines: {node: '>=v18'}
+
+ '@commitlint/parse@20.5.0':
+ resolution: {integrity: sha512-SeKWHBMk7YOTnnEWUhx+d1a9vHsjjuo6Uo1xRfPNfeY4bdYFasCH1dDpAv13Lyn+dDPOels+jP6D2GRZqzc5fA==}
+ engines: {node: '>=v18'}
+
+ '@commitlint/read@20.5.0':
+ resolution: {integrity: sha512-JDEIJ2+GnWpK8QqwfmW7O42h0aycJEWNqcdkJnyzLD11nf9dW2dWLTVEa8Wtlo4IZFGLPATjR5neA5QlOvIH1w==}
+ engines: {node: '>=v18'}
+
+ '@commitlint/resolve-extends@20.5.0':
+ resolution: {integrity: sha512-3SHPWUW2v0tyspCTcfSsYml0gses92l6TlogwzvM2cbxDgmhSRc+fldDjvGkCXJrjSM87BBaWYTPWwwyASZRrg==}
+ engines: {node: '>=v18'}
+
+ '@commitlint/rules@20.5.0':
+ resolution: {integrity: sha512-5NdQXQEdnDPT5pK8O39ZA7HohzPRHEsDGU23cyVCNPQy4WegAbAwrQk3nIu7p2sl3dutPk8RZd91yKTrMTnRkQ==}
+ engines: {node: '>=v18'}
+
+ '@commitlint/to-lines@20.0.0':
+ resolution: {integrity: sha512-2l9gmwiCRqZNWgV+pX1X7z4yP0b3ex/86UmUFgoRt672Ez6cAM2lOQeHFRUTuE6sPpi8XBCGnd8Kh3bMoyHwJw==}
+ engines: {node: '>=v18'}
+
+ '@commitlint/top-level@20.4.3':
+ resolution: {integrity: sha512-qD9xfP6dFg5jQ3NMrOhG0/w5y3bBUsVGyJvXxdWEwBm8hyx4WOk3kKXw28T5czBYvyeCVJgJJ6aoJZUWDpaacQ==}
+ engines: {node: '>=v18'}
+
+ '@commitlint/types@20.5.0':
+ resolution: {integrity: sha512-ZJoS8oSq2CAZEpc/YI9SulLrdiIyXeHb/OGqGrkUP6Q7YV+0ouNAa7GjqRdXeQPncHQIDz/jbCTlHScvYvO/gA==}
+ engines: {node: '>=v18'}
+
+ '@conventional-changelog/git-client@2.6.0':
+ resolution: {integrity: sha512-T+uPDciKf0/ioNNDpMGc8FDsehJClZP0yR3Q5MN6wE/Y/1QZ7F+80OgznnTCOlMEG4AV0LvH2UJi3C/nBnaBUg==}
+ engines: {node: '>=18'}
+ peerDependencies:
+ conventional-commits-filter: ^5.0.0
+ conventional-commits-parser: ^6.3.0
+ peerDependenciesMeta:
+ conventional-commits-filter:
+ optional: true
+ conventional-commits-parser:
+ optional: true
+
+ '@csstools/color-helpers@6.0.2':
+ resolution: {integrity: sha512-LMGQLS9EuADloEFkcTBR3BwV/CGHV7zyDxVRtVDTwdI2Ca4it0CCVTT9wCkxSgokjE5Ho41hEPgb8OEUwoXr6Q==}
+ engines: {node: '>=20.19.0'}
+
+ '@csstools/css-calc@3.1.1':
+ resolution: {integrity: sha512-HJ26Z/vmsZQqs/o3a6bgKslXGFAungXGbinULZO3eMsOyNJHeBBZfup5FiZInOghgoM4Hwnmw+OgbJCNg1wwUQ==}
+ engines: {node: '>=20.19.0'}
+ peerDependencies:
+ '@csstools/css-parser-algorithms': ^4.0.0
+ '@csstools/css-tokenizer': ^4.0.0
+
+ '@csstools/css-color-parser@4.0.2':
+ resolution: {integrity: sha512-0GEfbBLmTFf0dJlpsNU7zwxRIH0/BGEMuXLTCvFYxuL1tNhqzTbtnFICyJLTNK4a+RechKP75e7w42ClXSnJQw==}
+ engines: {node: '>=20.19.0'}
+ peerDependencies:
+ '@csstools/css-parser-algorithms': ^4.0.0
+ '@csstools/css-tokenizer': ^4.0.0
+
+ '@csstools/css-parser-algorithms@4.0.0':
+ resolution: {integrity: sha512-+B87qS7fIG3L5h3qwJ/IFbjoVoOe/bpOdh9hAjXbvx0o8ImEmUsGXN0inFOnk2ChCFgqkkGFQ+TpM5rbhkKe4w==}
+ engines: {node: '>=20.19.0'}
+ peerDependencies:
+ '@csstools/css-tokenizer': ^4.0.0
+
+ '@csstools/css-syntax-patches-for-csstree@1.1.1':
+ resolution: {integrity: sha512-BvqN0AMWNAnLk9G8jnUT77D+mUbY/H2b3uDTvg2isJkHaOufUE2R3AOwxWo7VBQKT1lOdwdvorddo2B/lk64+w==}
+ peerDependencies:
+ css-tree: ^3.2.1
+ peerDependenciesMeta:
+ css-tree:
+ optional: true
+
+ '@csstools/css-tokenizer@4.0.0':
+ resolution: {integrity: sha512-QxULHAm7cNu72w97JUNCBFODFaXpbDg+dP8b/oWFAZ2MTRppA3U00Y2L1HqaS4J6yBqxwa/Y3nMBaxVKbB/NsA==}
+ engines: {node: '>=20.19.0'}
+
+ '@emmetio/abbreviation@2.3.3':
+ resolution: {integrity: sha512-mgv58UrU3rh4YgbE/TzgLQwJ3pFsHHhCLqY20aJq+9comytTXUDNGG/SMtSeMJdkpxgXSXunBGLD8Boka3JyVA==}
+
+ '@emmetio/css-abbreviation@2.1.8':
+ resolution: {integrity: sha512-s9yjhJ6saOO/uk1V74eifykk2CBYi01STTK3WlXWGOepyKa23ymJ053+DNQjpFcy1ingpaO7AxCcwLvHFY9tuw==}
+
+ '@emmetio/css-parser@0.4.1':
+ resolution: {integrity: sha512-2bC6m0MV/voF4CTZiAbG5MWKbq5EBmDPKu9Sb7s7nVcEzNQlrZP6mFFFlIaISM8X6514H9shWMme1fCm8cWAfQ==}
+
+ '@emmetio/html-matcher@1.3.0':
+ resolution: {integrity: sha512-NTbsvppE5eVyBMuyGfVu2CRrLvo7J4YHb6t9sBFLyY03WYhXET37qA4zOYUjBWFCRHO7pS1B9khERtY0f5JXPQ==}
+
+ '@emmetio/scanner@1.0.4':
+ resolution: {integrity: sha512-IqRuJtQff7YHHBk4G8YZ45uB9BaAGcwQeVzgj/zj8/UdOhtQpEIupUhSk8dys6spFIWVZVeK20CzGEnqR5SbqA==}
+
+ '@emmetio/stream-reader-utils@0.1.0':
+ resolution: {integrity: sha512-ZsZ2I9Vzso3Ho/pjZFsmmZ++FWeEd/txqybHTm4OgaZzdS8V9V/YYWQwg5TC38Z7uLWUV1vavpLLbjJtKubR1A==}
+
+ '@emmetio/stream-reader@2.2.0':
+ resolution: {integrity: sha512-fXVXEyFA5Yv3M3n8sUGT7+fvecGrZP4k6FnWWMSZVQf69kAq0LLpaBQLGcPR30m3zMmKYhECP4k/ZkzvhEW5kw==}
+
+ '@emnapi/runtime@1.9.1':
+ resolution: {integrity: sha512-VYi5+ZVLhpgK4hQ0TAjiQiZ6ol0oe4mBx7mVv7IflsiEp0OWoVsp/+f9Vc1hOhE0TtkORVrI1GvzyreqpgWtkA==}
+
+ '@esbuild/aix-ppc64@0.27.4':
+ resolution: {integrity: sha512-cQPwL2mp2nSmHHJlCyoXgHGhbEPMrEEU5xhkcy3Hs/O7nGZqEpZ2sUtLaL9MORLtDfRvVl2/3PAuEkYZH0Ty8Q==}
+ engines: {node: '>=18'}
+ cpu: [ppc64]
+ os: [aix]
+
+ '@esbuild/android-arm64@0.27.4':
+ resolution: {integrity: sha512-gdLscB7v75wRfu7QSm/zg6Rx29VLdy9eTr2t44sfTW7CxwAtQghZ4ZnqHk3/ogz7xao0QAgrkradbBzcqFPasw==}
+ engines: {node: '>=18'}
+ cpu: [arm64]
+ os: [android]
+
+ '@esbuild/android-arm@0.27.4':
+ resolution: {integrity: sha512-X9bUgvxiC8CHAGKYufLIHGXPJWnr0OCdR0anD2e21vdvgCI8lIfqFbnoeOz7lBjdrAGUhqLZLcQo6MLhTO2DKQ==}
+ engines: {node: '>=18'}
+ cpu: [arm]
+ os: [android]
+
+ '@esbuild/android-x64@0.27.4':
+ resolution: {integrity: sha512-PzPFnBNVF292sfpfhiyiXCGSn9HZg5BcAz+ivBuSsl6Rk4ga1oEXAamhOXRFyMcjwr2DVtm40G65N3GLeH1Lvw==}
+ engines: {node: '>=18'}
+ cpu: [x64]
+ os: [android]
+
+ '@esbuild/darwin-arm64@0.27.4':
+ resolution: {integrity: sha512-b7xaGIwdJlht8ZFCvMkpDN6uiSmnxxK56N2GDTMYPr2/gzvfdQN8rTfBsvVKmIVY/X7EM+/hJKEIbbHs9oA4tQ==}
+ engines: {node: '>=18'}
+ cpu: [arm64]
+ os: [darwin]
+
+ '@esbuild/darwin-x64@0.27.4':
+ resolution: {integrity: sha512-sR+OiKLwd15nmCdqpXMnuJ9W2kpy0KigzqScqHI3Hqwr7IXxBp3Yva+yJwoqh7rE8V77tdoheRYataNKL4QrPw==}
+ engines: {node: '>=18'}
+ cpu: [x64]
+ os: [darwin]
+
+ '@esbuild/freebsd-arm64@0.27.4':
+ resolution: {integrity: sha512-jnfpKe+p79tCnm4GVav68A7tUFeKQwQyLgESwEAUzyxk/TJr4QdGog9sqWNcUbr/bZt/O/HXouspuQDd9JxFSw==}
+ engines: {node: '>=18'}
+ cpu: [arm64]
+ os: [freebsd]
+
+ '@esbuild/freebsd-x64@0.27.4':
+ resolution: {integrity: sha512-2kb4ceA/CpfUrIcTUl1wrP/9ad9Atrp5J94Lq69w7UwOMolPIGrfLSvAKJp0RTvkPPyn6CIWrNy13kyLikZRZQ==}
+ engines: {node: '>=18'}
+ cpu: [x64]
+ os: [freebsd]
+
+ '@esbuild/linux-arm64@0.27.4':
+ resolution: {integrity: sha512-7nQOttdzVGth1iz57kxg9uCz57dxQLHWxopL6mYuYthohPKEK0vU0C3O21CcBK6KDlkYVcnDXY099HcCDXd9dA==}
+ engines: {node: '>=18'}
+ cpu: [arm64]
+ os: [linux]
+
+ '@esbuild/linux-arm@0.27.4':
+ resolution: {integrity: sha512-aBYgcIxX/wd5n2ys0yESGeYMGF+pv6g0DhZr3G1ZG4jMfruU9Tl1i2Z+Wnj9/KjGz1lTLCcorqE2viePZqj4Eg==}
+ engines: {node: '>=18'}
+ cpu: [arm]
+ os: [linux]
+
+ '@esbuild/linux-ia32@0.27.4':
+ resolution: {integrity: sha512-oPtixtAIzgvzYcKBQM/qZ3R+9TEUd1aNJQu0HhGyqtx6oS7qTpvjheIWBbes4+qu1bNlo2V4cbkISr8q6gRBFA==}
+ engines: {node: '>=18'}
+ cpu: [ia32]
+ os: [linux]
+
+ '@esbuild/linux-loong64@0.27.4':
+ resolution: {integrity: sha512-8mL/vh8qeCoRcFH2nM8wm5uJP+ZcVYGGayMavi8GmRJjuI3g1v6Z7Ni0JJKAJW+m0EtUuARb6Lmp4hMjzCBWzA==}
+ engines: {node: '>=18'}
+ cpu: [loong64]
+ os: [linux]
+
+ '@esbuild/linux-mips64el@0.27.4':
+ resolution: {integrity: sha512-1RdrWFFiiLIW7LQq9Q2NES+HiD4NyT8Itj9AUeCl0IVCA459WnPhREKgwrpaIfTOe+/2rdntisegiPWn/r/aAw==}
+ engines: {node: '>=18'}
+ cpu: [mips64el]
+ os: [linux]
+
+ '@esbuild/linux-ppc64@0.27.4':
+ resolution: {integrity: sha512-tLCwNG47l3sd9lpfyx9LAGEGItCUeRCWeAx6x2Jmbav65nAwoPXfewtAdtbtit/pJFLUWOhpv0FpS6GQAmPrHA==}
+ engines: {node: '>=18'}
+ cpu: [ppc64]
+ os: [linux]
+
+ '@esbuild/linux-riscv64@0.27.4':
+ resolution: {integrity: sha512-BnASypppbUWyqjd1KIpU4AUBiIhVr6YlHx/cnPgqEkNoVOhHg+YiSVxM1RLfiy4t9cAulbRGTNCKOcqHrEQLIw==}
+ engines: {node: '>=18'}
+ cpu: [riscv64]
+ os: [linux]
+
+ '@esbuild/linux-s390x@0.27.4':
+ resolution: {integrity: sha512-+eUqgb/Z7vxVLezG8bVB9SfBie89gMueS+I0xYh2tJdw3vqA/0ImZJ2ROeWwVJN59ihBeZ7Tu92dF/5dy5FttA==}
+ engines: {node: '>=18'}
+ cpu: [s390x]
+ os: [linux]
+
+ '@esbuild/linux-x64@0.27.4':
+ resolution: {integrity: sha512-S5qOXrKV8BQEzJPVxAwnryi2+Iq5pB40gTEIT69BQONqR7JH1EPIcQ/Uiv9mCnn05jff9umq/5nqzxlqTOg9NA==}
+ engines: {node: '>=18'}
+ cpu: [x64]
+ os: [linux]
+
+ '@esbuild/netbsd-arm64@0.27.4':
+ resolution: {integrity: sha512-xHT8X4sb0GS8qTqiwzHqpY00C95DPAq7nAwX35Ie/s+LO9830hrMd3oX0ZMKLvy7vsonee73x0lmcdOVXFzd6Q==}
+ engines: {node: '>=18'}
+ cpu: [arm64]
+ os: [netbsd]
+
+ '@esbuild/netbsd-x64@0.27.4':
+ resolution: {integrity: sha512-RugOvOdXfdyi5Tyv40kgQnI0byv66BFgAqjdgtAKqHoZTbTF2QqfQrFwa7cHEORJf6X2ht+l9ABLMP0dnKYsgg==}
+ engines: {node: '>=18'}
+ cpu: [x64]
+ os: [netbsd]
+
+ '@esbuild/openbsd-arm64@0.27.4':
+ resolution: {integrity: sha512-2MyL3IAaTX+1/qP0O1SwskwcwCoOI4kV2IBX1xYnDDqthmq5ArrW94qSIKCAuRraMgPOmG0RDTA74mzYNQA9ow==}
+ engines: {node: '>=18'}
+ cpu: [arm64]
+ os: [openbsd]
+
+ '@esbuild/openbsd-x64@0.27.4':
+ resolution: {integrity: sha512-u8fg/jQ5aQDfsnIV6+KwLOf1CmJnfu1ShpwqdwC0uA7ZPwFws55Ngc12vBdeUdnuWoQYx/SOQLGDcdlfXhYmXQ==}
+ engines: {node: '>=18'}
+ cpu: [x64]
+ os: [openbsd]
+
+ '@esbuild/openharmony-arm64@0.27.4':
+ resolution: {integrity: sha512-JkTZrl6VbyO8lDQO3yv26nNr2RM2yZzNrNHEsj9bm6dOwwu9OYN28CjzZkH57bh4w0I2F7IodpQvUAEd1mbWXg==}
+ engines: {node: '>=18'}
+ cpu: [arm64]
+ os: [openharmony]
+
+ '@esbuild/sunos-x64@0.27.4':
+ resolution: {integrity: sha512-/gOzgaewZJfeJTlsWhvUEmUG4tWEY2Spp5M20INYRg2ZKl9QPO3QEEgPeRtLjEWSW8FilRNacPOg8R1uaYkA6g==}
+ engines: {node: '>=18'}
+ cpu: [x64]
+ os: [sunos]
+
+ '@esbuild/win32-arm64@0.27.4':
+ resolution: {integrity: sha512-Z9SExBg2y32smoDQdf1HRwHRt6vAHLXcxD2uGgO/v2jK7Y718Ix4ndsbNMU/+1Qiem9OiOdaqitioZwxivhXYg==}
+ engines: {node: '>=18'}
+ cpu: [arm64]
+ os: [win32]
+
+ '@esbuild/win32-ia32@0.27.4':
+ resolution: {integrity: sha512-DAyGLS0Jz5G5iixEbMHi5KdiApqHBWMGzTtMiJ72ZOLhbu/bzxgAe8Ue8CTS3n3HbIUHQz/L51yMdGMeoxXNJw==}
+ engines: {node: '>=18'}
+ cpu: [ia32]
+ os: [win32]
+
+ '@esbuild/win32-x64@0.27.4':
+ resolution: {integrity: sha512-+knoa0BDoeXgkNvvV1vvbZX4+hizelrkwmGJBdT17t8FNPwG2lKemmuMZlmaNQ3ws3DKKCxpb4zRZEIp3UxFCg==}
+ engines: {node: '>=18'}
+ cpu: [x64]
+ os: [win32]
+
+ '@exodus/bytes@1.15.0':
+ resolution: {integrity: sha512-UY0nlA+feH81UGSHv92sLEPLCeZFjXOuHhrIo0HQydScuQc8s0A7kL/UdgwgDq8g8ilksmuoF35YVTNphV2aBQ==}
+ engines: {node: ^20.19.0 || ^22.12.0 || >=24.0.0}
+ peerDependencies:
+ '@noble/hashes': ^1.8.0 || ^2.0.0
+ peerDependenciesMeta:
+ '@noble/hashes':
+ optional: true
+
+ '@iconify-json/lucide@1.2.98':
+ resolution: {integrity: sha512-Lx2464W8Tty/QEnZ2UPb73nPdML/HpGCj0J0w37jP3/jx3l4fniZBjDxe1TgHiIL5XW9QO3vlx53ZQZ5JsNpzQ==}
+
+ '@iconify/tools@4.2.0':
+ resolution: {integrity: sha512-WRxPva/ipxYkqZd1+CkEAQmd86dQmrwH0vwK89gmp2Kh2WyyVw57XbPng0NehP3x4V1LzLsXUneP1uMfTMZmUA==}
+
+ '@iconify/types@2.0.0':
+ resolution: {integrity: sha512-+wluvCrRhXrhyOmRDJ3q8mux9JkKy5SJ/v8ol2tu4FVjyYvtEzkc/3pK15ET6RKg4b4w4BmTk1+gsCUhf21Ykg==}
+
+ '@iconify/utils@2.3.0':
+ resolution: {integrity: sha512-GmQ78prtwYW6EtzXRU1rY+KwOKfz32PD7iJh6Iyqw68GiKuoZ2A6pRtzWONz5VQJbp50mEjXh/7NkumtrAgRKA==}
+
+ '@img/colour@1.1.0':
+ resolution: {integrity: sha512-Td76q7j57o/tLVdgS746cYARfSyxk8iEfRxewL9h4OMzYhbW4TAcppl0mT4eyqXddh6L/jwoM75mo7ixa/pCeQ==}
+ engines: {node: '>=18'}
+
+ '@img/sharp-darwin-arm64@0.34.5':
+ resolution: {integrity: sha512-imtQ3WMJXbMY4fxb/Ndp6HBTNVtWCUI0WdobyheGf5+ad6xX8VIDO8u2xE4qc/fr08CKG/7dDseFtn6M6g/r3w==}
+ engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
+ cpu: [arm64]
+ os: [darwin]
+
+ '@img/sharp-darwin-x64@0.34.5':
+ resolution: {integrity: sha512-YNEFAF/4KQ/PeW0N+r+aVVsoIY0/qxxikF2SWdp+NRkmMB7y9LBZAVqQ4yhGCm/H3H270OSykqmQMKLBhBJDEw==}
+ engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
+ cpu: [x64]
+ os: [darwin]
+
+ '@img/sharp-libvips-darwin-arm64@1.2.4':
+ resolution: {integrity: sha512-zqjjo7RatFfFoP0MkQ51jfuFZBnVE2pRiaydKJ1G/rHZvnsrHAOcQALIi9sA5co5xenQdTugCvtb1cuf78Vf4g==}
+ cpu: [arm64]
+ os: [darwin]
+
+ '@img/sharp-libvips-darwin-x64@1.2.4':
+ resolution: {integrity: sha512-1IOd5xfVhlGwX+zXv2N93k0yMONvUlANylbJw1eTah8K/Jtpi15KC+WSiaX/nBmbm2HxRM1gZ0nSdjSsrZbGKg==}
+ cpu: [x64]
+ os: [darwin]
+
+ '@img/sharp-libvips-linux-arm64@1.2.4':
+ resolution: {integrity: sha512-excjX8DfsIcJ10x1Kzr4RcWe1edC9PquDRRPx3YVCvQv+U5p7Yin2s32ftzikXojb1PIFc/9Mt28/y+iRklkrw==}
+ cpu: [arm64]
+ os: [linux]
+
+ '@img/sharp-libvips-linux-arm@1.2.4':
+ resolution: {integrity: sha512-bFI7xcKFELdiNCVov8e44Ia4u2byA+l3XtsAj+Q8tfCwO6BQ8iDojYdvoPMqsKDkuoOo+X6HZA0s0q11ANMQ8A==}
+ cpu: [arm]
+ os: [linux]
+
+ '@img/sharp-libvips-linux-ppc64@1.2.4':
+ resolution: {integrity: sha512-FMuvGijLDYG6lW+b/UvyilUWu5Ayu+3r2d1S8notiGCIyYU/76eig1UfMmkZ7vwgOrzKzlQbFSuQfgm7GYUPpA==}
+ cpu: [ppc64]
+ os: [linux]
+
+ '@img/sharp-libvips-linux-riscv64@1.2.4':
+ resolution: {integrity: sha512-oVDbcR4zUC0ce82teubSm+x6ETixtKZBh/qbREIOcI3cULzDyb18Sr/Wcyx7NRQeQzOiHTNbZFF1UwPS2scyGA==}
+ cpu: [riscv64]
+ os: [linux]
+
+ '@img/sharp-libvips-linux-s390x@1.2.4':
+ resolution: {integrity: sha512-qmp9VrzgPgMoGZyPvrQHqk02uyjA0/QrTO26Tqk6l4ZV0MPWIW6LTkqOIov+J1yEu7MbFQaDpwdwJKhbJvuRxQ==}
+ cpu: [s390x]
+ os: [linux]
+
+ '@img/sharp-libvips-linux-x64@1.2.4':
+ resolution: {integrity: sha512-tJxiiLsmHc9Ax1bz3oaOYBURTXGIRDODBqhveVHonrHJ9/+k89qbLl0bcJns+e4t4rvaNBxaEZsFtSfAdquPrw==}
+ cpu: [x64]
+ os: [linux]
+
+ '@img/sharp-libvips-linuxmusl-arm64@1.2.4':
+ resolution: {integrity: sha512-FVQHuwx1IIuNow9QAbYUzJ+En8KcVm9Lk5+uGUQJHaZmMECZmOlix9HnH7n1TRkXMS0pGxIJokIVB9SuqZGGXw==}
+ cpu: [arm64]
+ os: [linux]
+
+ '@img/sharp-libvips-linuxmusl-x64@1.2.4':
+ resolution: {integrity: sha512-+LpyBk7L44ZIXwz/VYfglaX/okxezESc6UxDSoyo2Ks6Jxc4Y7sGjpgU9s4PMgqgjj1gZCylTieNamqA1MF7Dg==}
+ cpu: [x64]
+ os: [linux]
+
+ '@img/sharp-linux-arm64@0.34.5':
+ resolution: {integrity: sha512-bKQzaJRY/bkPOXyKx5EVup7qkaojECG6NLYswgktOZjaXecSAeCWiZwwiFf3/Y+O1HrauiE3FVsGxFg8c24rZg==}
+ engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
+ cpu: [arm64]
+ os: [linux]
+
+ '@img/sharp-linux-arm@0.34.5':
+ resolution: {integrity: sha512-9dLqsvwtg1uuXBGZKsxem9595+ujv0sJ6Vi8wcTANSFpwV/GONat5eCkzQo/1O6zRIkh0m/8+5BjrRr7jDUSZw==}
+ engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
+ cpu: [arm]
+ os: [linux]
+
+ '@img/sharp-linux-ppc64@0.34.5':
+ resolution: {integrity: sha512-7zznwNaqW6YtsfrGGDA6BRkISKAAE1Jo0QdpNYXNMHu2+0dTrPflTLNkpc8l7MUP5M16ZJcUvysVWWrMefZquA==}
+ engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
+ cpu: [ppc64]
+ os: [linux]
+
+ '@img/sharp-linux-riscv64@0.34.5':
+ resolution: {integrity: sha512-51gJuLPTKa7piYPaVs8GmByo7/U7/7TZOq+cnXJIHZKavIRHAP77e3N2HEl3dgiqdD/w0yUfiJnII77PuDDFdw==}
+ engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
+ cpu: [riscv64]
+ os: [linux]
+
+ '@img/sharp-linux-s390x@0.34.5':
+ resolution: {integrity: sha512-nQtCk0PdKfho3eC5MrbQoigJ2gd1CgddUMkabUj+rBevs8tZ2cULOx46E7oyX+04WGfABgIwmMC0VqieTiR4jg==}
+ engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
+ cpu: [s390x]
+ os: [linux]
+
+ '@img/sharp-linux-x64@0.34.5':
+ resolution: {integrity: sha512-MEzd8HPKxVxVenwAa+JRPwEC7QFjoPWuS5NZnBt6B3pu7EG2Ge0id1oLHZpPJdn3OQK+BQDiw9zStiHBTJQQQQ==}
+ engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
+ cpu: [x64]
+ os: [linux]
+
+ '@img/sharp-linuxmusl-arm64@0.34.5':
+ resolution: {integrity: sha512-fprJR6GtRsMt6Kyfq44IsChVZeGN97gTD331weR1ex1c1rypDEABN6Tm2xa1wE6lYb5DdEnk03NZPqA7Id21yg==}
+ engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
+ cpu: [arm64]
+ os: [linux]
+
+ '@img/sharp-linuxmusl-x64@0.34.5':
+ resolution: {integrity: sha512-Jg8wNT1MUzIvhBFxViqrEhWDGzqymo3sV7z7ZsaWbZNDLXRJZoRGrjulp60YYtV4wfY8VIKcWidjojlLcWrd8Q==}
+ engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
+ cpu: [x64]
+ os: [linux]
+
+ '@img/sharp-wasm32@0.34.5':
+ resolution: {integrity: sha512-OdWTEiVkY2PHwqkbBI8frFxQQFekHaSSkUIJkwzclWZe64O1X4UlUjqqqLaPbUpMOQk6FBu/HtlGXNblIs0huw==}
+ engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
+ cpu: [wasm32]
+
+ '@img/sharp-win32-arm64@0.34.5':
+ resolution: {integrity: sha512-WQ3AgWCWYSb2yt+IG8mnC6Jdk9Whs7O0gxphblsLvdhSpSTtmu69ZG1Gkb6NuvxsNACwiPV6cNSZNzt0KPsw7g==}
+ engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
+ cpu: [arm64]
+ os: [win32]
+
+ '@img/sharp-win32-ia32@0.34.5':
+ resolution: {integrity: sha512-FV9m/7NmeCmSHDD5j4+4pNI8Cp3aW+JvLoXcTUo0IqyjSfAZJ8dIUmijx1qaJsIiU+Hosw6xM5KijAWRJCSgNg==}
+ engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
+ cpu: [ia32]
+ os: [win32]
+
+ '@img/sharp-win32-x64@0.34.5':
+ resolution: {integrity: sha512-+29YMsqY2/9eFEiW93eqWnuLcWcufowXewwSNIT6UwZdUUCrM3oFjMWH/Z6/TMmb4hlFenmfAVbpWeup2jryCw==}
+ engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
+ cpu: [x64]
+ os: [win32]
+
+ '@isaacs/fs-minipass@4.0.1':
+ resolution: {integrity: sha512-wgm9Ehl2jpeqP3zw/7mo3kRHFp5MEDhqAdwy1fTGkHAwnkGOVsgpvQhL8B5n1qlb01jV3n/bI0ZfZp5lWA1k4w==}
+ engines: {node: '>=18.0.0'}
+
+ '@jridgewell/gen-mapping@0.3.13':
+ resolution: {integrity: sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==}
+
+ '@jridgewell/remapping@2.3.5':
+ resolution: {integrity: sha512-LI9u/+laYG4Ds1TDKSJW2YPrIlcVYOwi2fUC6xB43lueCjgxV4lffOCZCtYFiH6TNOX+tQKXx97T4IKHbhyHEQ==}
+
+ '@jridgewell/resolve-uri@3.1.2':
+ resolution: {integrity: sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==}
+ engines: {node: '>=6.0.0'}
+
+ '@jridgewell/sourcemap-codec@1.5.5':
+ resolution: {integrity: sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==}
+
+ '@jridgewell/trace-mapping@0.3.31':
+ resolution: {integrity: sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==}
+
+ '@oslojs/encoding@1.1.0':
+ resolution: {integrity: sha512-70wQhgYmndg4GCPxPPxPGevRKqTIJ2Nh4OkiMWmDAVYsTQ+Ta7Sq+rPevXyXGdzr30/qZBnyOalCszoMxlyldQ==}
+
+ '@oxfmt/binding-android-arm-eabi@0.41.0':
+ resolution: {integrity: sha512-REfrqeMKGkfMP+m/ScX4f5jJBSmVNYcpoDF8vP8f8eYPDuPGZmzp56NIUsYmx3h7f6NzC6cE3gqh8GDWrJHCKw==}
+ engines: {node: ^20.19.0 || >=22.12.0}
+ cpu: [arm]
+ os: [android]
+
+ '@oxfmt/binding-android-arm64@0.41.0':
+ resolution: {integrity: sha512-s0b1dxNgb2KomspFV2LfogC2XtSJB42POXF4bMCLJyvQmAGos4ZtjGPfQreToQEaY0FQFjz3030ggI36rF1q5g==}
+ engines: {node: ^20.19.0 || >=22.12.0}
+ cpu: [arm64]
+ os: [android]
+
+ '@oxfmt/binding-darwin-arm64@0.41.0':
+ resolution: {integrity: sha512-EGXGualADbv/ZmamE7/2DbsrYmjoPlAmHEpTL4vapLF4EfVD6fr8/uQDFnPJkUBjiSWFJZtFNsGeN1B6V3owmA==}
+ engines: {node: ^20.19.0 || >=22.12.0}
+ cpu: [arm64]
+ os: [darwin]
+
+ '@oxfmt/binding-darwin-x64@0.41.0':
+ resolution: {integrity: sha512-WxySJEvdQQYMmyvISH3qDpTvoS0ebnIP63IMxLLWowJyPp/AAH0hdWtlo+iGNK5y3eVfa5jZguwNaQkDKWpGSw==}
+ engines: {node: ^20.19.0 || >=22.12.0}
+ cpu: [x64]
+ os: [darwin]
+
+ '@oxfmt/binding-freebsd-x64@0.41.0':
+ resolution: {integrity: sha512-Y2kzMkv3U3oyuYaR4wTfGjOTYTXiFC/hXmG0yVASKkbh02BJkvD98Ij8bIevr45hNZ0DmZEgqiXF+9buD4yMYQ==}
+ engines: {node: ^20.19.0 || >=22.12.0}
+ cpu: [x64]
+ os: [freebsd]
+
+ '@oxfmt/binding-linux-arm-gnueabihf@0.41.0':
+ resolution: {integrity: sha512-ptazDjdUyhket01IjPTT6ULS1KFuBfTUU97osTP96X5y/0oso+AgAaJzuH81oP0+XXyrWIHbRzozSAuQm4p48g==}
+ engines: {node: ^20.19.0 || >=22.12.0}
+ cpu: [arm]
+ os: [linux]
+
+ '@oxfmt/binding-linux-arm-musleabihf@0.41.0':
+ resolution: {integrity: sha512-UkoL2OKxFD+56bPEBcdGn+4juTW4HRv/T6w1dIDLnvKKWr6DbarB/mtHXlADKlFiJubJz8pRkttOR7qjYR6lTA==}
+ engines: {node: ^20.19.0 || >=22.12.0}
+ cpu: [arm]
+ os: [linux]
+
+ '@oxfmt/binding-linux-arm64-gnu@0.41.0':
+ resolution: {integrity: sha512-gofu0PuumSOHYczD8p62CPY4UF6ee+rSLZJdUXkpwxg6pILiwSDBIouPskjF/5nF3A7QZTz2O9KFNkNxxFN9tA==}
+ engines: {node: ^20.19.0 || >=22.12.0}
+ cpu: [arm64]
+ os: [linux]
+
+ '@oxfmt/binding-linux-arm64-musl@0.41.0':
+ resolution: {integrity: sha512-VfVZxL0+6RU86T8F8vKiDBa+iHsr8PAjQmKGBzSCAX70b6x+UOMFl+2dNihmKmUwqkCazCPfYjt6SuAPOeQJ3g==}
+ engines: {node: ^20.19.0 || >=22.12.0}
+ cpu: [arm64]
+ os: [linux]
+
+ '@oxfmt/binding-linux-ppc64-gnu@0.41.0':
+ resolution: {integrity: sha512-bwzokz2eGvdfJbc0i+zXMJ4BBjQPqg13jyWpEEZDOrBCQ91r8KeY2Mi2kUeuMTZNFXju+jcAbAbpyJxRGla0eg==}
+ engines: {node: ^20.19.0 || >=22.12.0}
+ cpu: [ppc64]
+ os: [linux]
+
+ '@oxfmt/binding-linux-riscv64-gnu@0.41.0':
+ resolution: {integrity: sha512-POLM//PCH9uqDeNDwWL3b3DkMmI3oI2cU6hwc2lnztD1o7dzrQs3R9nq555BZ6wI7t2lyhT9CS+CRaz5X0XqLA==}
+ engines: {node: ^20.19.0 || >=22.12.0}
+ cpu: [riscv64]
+ os: [linux]
+
+ '@oxfmt/binding-linux-riscv64-musl@0.41.0':
+ resolution: {integrity: sha512-NNK7PzhFqLUwx/G12Xtm6scGv7UITvyGdAR5Y+TlqsG+essnuRWR4jRNODWRjzLZod0T3SayRbnkSIWMBov33w==}
+ engines: {node: ^20.19.0 || >=22.12.0}
+ cpu: [riscv64]
+ os: [linux]
+
+ '@oxfmt/binding-linux-s390x-gnu@0.41.0':
+ resolution: {integrity: sha512-qVf/zDC5cN9eKe4qI/O/m445er1IRl6swsSl7jHkqmOSVfknwCe5JXitYjZca+V/cNJSU/xPlC5EFMabMMFDpw==}
+ engines: {node: ^20.19.0 || >=22.12.0}
+ cpu: [s390x]
+ os: [linux]
+
+ '@oxfmt/binding-linux-x64-gnu@0.41.0':
+ resolution: {integrity: sha512-ojxYWu7vUb6ysYqVCPHuAPVZHAI40gfZ0PDtZAMwVmh2f0V8ExpPIKoAKr7/8sNbAXJBBpZhs2coypIo2jJX4w==}
+ engines: {node: ^20.19.0 || >=22.12.0}
+ cpu: [x64]
+ os: [linux]
+
+ '@oxfmt/binding-linux-x64-musl@0.41.0':
+ resolution: {integrity: sha512-O2exZLBxoCMIv2vlvcbkdedazJPTdG0VSup+0QUCfYQtx751zCZNboX2ZUOiQ/gDTdhtXvSiot0h6GEGkOyalA==}
+ engines: {node: ^20.19.0 || >=22.12.0}
+ cpu: [x64]
+ os: [linux]
+
+ '@oxfmt/binding-openharmony-arm64@0.41.0':
+ resolution: {integrity: sha512-N+31/VoL+z+NNBt8viy3I4NaIdPbiYeOnB884LKqvXldaE2dRztdPv3q5ipfZYv0RwFp7JfqS4I27K/DSHCakg==}
+ engines: {node: ^20.19.0 || >=22.12.0}
+ cpu: [arm64]
+ os: [openharmony]
+
+ '@oxfmt/binding-win32-arm64-msvc@0.41.0':
+ resolution: {integrity: sha512-Z7NAtu/RN8kjCQ1y5oDD0nTAeRswh3GJ93qwcW51srmidP7XPBmZbLlwERu1W5veCevQJtPS9xmkpcDTYsGIwQ==}
+ engines: {node: ^20.19.0 || >=22.12.0}
+ cpu: [arm64]
+ os: [win32]
+
+ '@oxfmt/binding-win32-ia32-msvc@0.41.0':
+ resolution: {integrity: sha512-uNxxP3l4bJ6VyzIeRqCmBU2Q0SkCFgIhvx9/9dJ9V8t/v+jP1IBsuaLwCXGR8JPHtkj4tFp+RHtUmU2ZYAUpMA==}
+ engines: {node: ^20.19.0 || >=22.12.0}
+ cpu: [ia32]
+ os: [win32]
+
+ '@oxfmt/binding-win32-x64-msvc@0.41.0':
+ resolution: {integrity: sha512-49ZSpbZ1noozyPapE8SUOSm3IN0Ze4b5nkO+4+7fq6oEYQQJFhE0saj5k/Gg4oewVPdjn0L3ZFeWk2Vehjcw7A==}
+ engines: {node: ^20.19.0 || >=22.12.0}
+ cpu: [x64]
+ os: [win32]
+
+ '@oxlint/binding-android-arm-eabi@1.56.0':
+ resolution: {integrity: sha512-IyfYPthZyiSKwAv/dLjeO18SaK8MxLI9Yss2JrRDyweQAkuL3LhEy7pwIwI7uA3KQc1Vdn20kdmj3q0oUIQL6A==}
+ engines: {node: ^20.19.0 || >=22.12.0}
+ cpu: [arm]
+ os: [android]
+
+ '@oxlint/binding-android-arm64@1.56.0':
+ resolution: {integrity: sha512-Ga5zYrzH6vc/VFxhn6MmyUnYEfy9vRpwTIks99mY3j6Nz30yYpIkWryI0QKPCgvGUtDSXVLEaMum5nA+WrNOSg==}
+ engines: {node: ^20.19.0 || >=22.12.0}
+ cpu: [arm64]
+ os: [android]
+
+ '@oxlint/binding-darwin-arm64@1.56.0':
+ resolution: {integrity: sha512-ogmbdJysnw/D4bDcpf1sPLpFThZ48lYp4aKYm10Z/6Nh1SON6NtnNhTNOlhEY296tDFItsZUz+2tgcSYqh8Eyw==}
+ engines: {node: ^20.19.0 || >=22.12.0}
+ cpu: [arm64]
+ os: [darwin]
+
+ '@oxlint/binding-darwin-x64@1.56.0':
+ resolution: {integrity: sha512-x8QE1h+RAtQ2g+3KPsP6Fk/tdz6zJQUv5c7fTrJxXV3GHOo+Ry5p/PsogU4U+iUZg0rj6hS+E4xi+mnwwlDCWQ==}
+ engines: {node: ^20.19.0 || >=22.12.0}
+ cpu: [x64]
+ os: [darwin]
+
+ '@oxlint/binding-freebsd-x64@1.56.0':
+ resolution: {integrity: sha512-6G+WMZvwJpMvY7my+/SHEjb7BTk/PFbePqLpmVmUJRIsJMy/UlyYqjpuh0RCgYYkPLcnXm1rUM04kbTk8yS1Yg==}
+ engines: {node: ^20.19.0 || >=22.12.0}
+ cpu: [x64]
+ os: [freebsd]
+
+ '@oxlint/binding-linux-arm-gnueabihf@1.56.0':
+ resolution: {integrity: sha512-YYHBsk/sl7fYwQOok+6W5lBPeUEvisznV/HZD2IfZmF3Bns6cPC3Z0vCtSEOaAWTjYWN3jVsdu55jMxKlsdlhg==}
+ engines: {node: ^20.19.0 || >=22.12.0}
+ cpu: [arm]
+ os: [linux]
+
+ '@oxlint/binding-linux-arm-musleabihf@1.56.0':
+ resolution: {integrity: sha512-+AZK8rOUr78y8WT6XkDb04IbMRqauNV+vgT6f8ZLOH8wnpQ9i7Nol0XLxAu+Cq7Sb+J9wC0j6Km5hG8rj47/yQ==}
+ engines: {node: ^20.19.0 || >=22.12.0}
+ cpu: [arm]
+ os: [linux]
+
+ '@oxlint/binding-linux-arm64-gnu@1.56.0':
+ resolution: {integrity: sha512-urse2SnugwJRojUkGSSeH2LPMaje5Q50yQtvtL9HFckiyeqXzoFwOAZqD5TR29R2lq7UHidfFDM9EGcchcbb8A==}
+ engines: {node: ^20.19.0 || >=22.12.0}
+ cpu: [arm64]
+ os: [linux]
+
+ '@oxlint/binding-linux-arm64-musl@1.56.0':
+ resolution: {integrity: sha512-rkTZkBfJ4TYLjansjSzL6mgZOdN5IvUnSq3oNJSLwBcNvy3dlgQtpHPrRxrCEbbcp7oQ6If0tkNaqfOsphYZ9g==}
+ engines: {node: ^20.19.0 || >=22.12.0}
+ cpu: [arm64]
+ os: [linux]
+
+ '@oxlint/binding-linux-ppc64-gnu@1.56.0':
+ resolution: {integrity: sha512-uqL1kMH3u69/e1CH2EJhP3CP28jw2ExLsku4o8RVAZ7fySo9zOyI2fy9pVlTAp4voBLVgzndXi3SgtdyCTa2aA==}
+ engines: {node: ^20.19.0 || >=22.12.0}
+ cpu: [ppc64]
+ os: [linux]
+
+ '@oxlint/binding-linux-riscv64-gnu@1.56.0':
+ resolution: {integrity: sha512-j0CcMBOgV6KsRaBdsebIeiy7hCjEvq2KdEsiULf2LZqAq0v1M1lWjelhCV57LxsqaIGChXFuFJ0RiFrSRHPhSg==}
+ engines: {node: ^20.19.0 || >=22.12.0}
+ cpu: [riscv64]
+ os: [linux]
+
+ '@oxlint/binding-linux-riscv64-musl@1.56.0':
+ resolution: {integrity: sha512-7VDOiL8cDG3DQ/CY3yKjbV1c4YPvc4vH8qW09Vv+5ukq3l/Kcyr6XGCd5NvxUmxqDb2vjMpM+eW/4JrEEsUetA==}
+ engines: {node: ^20.19.0 || >=22.12.0}
+ cpu: [riscv64]
+ os: [linux]
+
+ '@oxlint/binding-linux-s390x-gnu@1.56.0':
+ resolution: {integrity: sha512-JGRpX0M+ikD3WpwJ7vKcHKV6Kg0dT52BW2Eu2BupXotYeqGXBrbY+QPkAyKO6MNgKozyTNaRh3r7g+VWgyAQYQ==}
+ engines: {node: ^20.19.0 || >=22.12.0}
+ cpu: [s390x]
+ os: [linux]
+
+ '@oxlint/binding-linux-x64-gnu@1.56.0':
+ resolution: {integrity: sha512-dNaICPvtmuxFP/VbqdofrLqdS3bM/AKJN3LMJD52si44ea7Be1cBk6NpfIahaysG9Uo+L98QKddU9CD5L8UHnQ==}
+ engines: {node: ^20.19.0 || >=22.12.0}
+ cpu: [x64]
+ os: [linux]
+
+ '@oxlint/binding-linux-x64-musl@1.56.0':
+ resolution: {integrity: sha512-pF1vOtM+GuXmbklM1hV8WMsn6tCNPvkUzklj/Ej98JhlanbmA2RB1BILgOpwSuCTRTIYx2MXssmEyQQ90QF5aA==}
+ engines: {node: ^20.19.0 || >=22.12.0}
+ cpu: [x64]
+ os: [linux]
+
+ '@oxlint/binding-openharmony-arm64@1.56.0':
+ resolution: {integrity: sha512-bp8NQ4RE6fDIFLa4bdBiOA+TAvkNkg+rslR+AvvjlLTYXLy9/uKAYLQudaQouWihLD/hgkrXIKKzXi5IXOewwg==}
+ engines: {node: ^20.19.0 || >=22.12.0}
+ cpu: [arm64]
+ os: [openharmony]
+
+ '@oxlint/binding-win32-arm64-msvc@1.56.0':
+ resolution: {integrity: sha512-PxT4OJDfMOQBzo3OlzFb9gkoSD+n8qSBxyVq2wQSZIHFQYGEqIRTo9M0ZStvZm5fdhMqaVYpOnJvH2hUMEDk/g==}
+ engines: {node: ^20.19.0 || >=22.12.0}
+ cpu: [arm64]
+ os: [win32]
+
+ '@oxlint/binding-win32-ia32-msvc@1.56.0':
+ resolution: {integrity: sha512-PTRy6sIEPqy2x8PTP1baBNReN/BNEFmde0L+mYeHmjXE1Vlcc9+I5nsqENsB2yAm5wLkzPoTNCMY/7AnabT4/A==}
+ engines: {node: ^20.19.0 || >=22.12.0}
+ cpu: [ia32]
+ os: [win32]
+
+ '@oxlint/binding-win32-x64-msvc@1.56.0':
+ resolution: {integrity: sha512-ZHa0clocjLmIDr+1LwoWtxRcoYniAvERotvwKUYKhH41NVfl0Y4LNbyQkwMZzwDvKklKGvGZ5+DAG58/Ik47tQ==}
+ engines: {node: ^20.19.0 || >=22.12.0}
+ cpu: [x64]
+ os: [win32]
+
+ '@playwright/test@1.58.2':
+ resolution: {integrity: sha512-akea+6bHYBBfA9uQqSYmlJXn61cTa+jbO87xVLCWbTqbWadRVmhxlXATaOjOgcBaWU4ePo0wB41KMFv3o35IXA==}
+ engines: {node: '>=18'}
+ hasBin: true
+
+ '@polka/url@1.0.0-next.29':
+ resolution: {integrity: sha512-wwQAWhWSuHaag8c4q/KN/vCoeOJYshAIvMQwD4GpSb3OiZklFfvAgmj0VCBBImRpuF/aFgIRzllXlVX93Jevww==}
+
+ '@rollup/pluginutils@5.3.0':
+ resolution: {integrity: sha512-5EdhGZtnu3V88ces7s53hhfK5KSASnJZv8Lulpc04cWO3REESroJXg73DFsOmgbU2BhwV0E20bu2IDZb3VKW4Q==}
+ engines: {node: '>=14.0.0'}
+ peerDependencies:
+ rollup: ^1.20.0||^2.0.0||^3.0.0||^4.0.0
+ peerDependenciesMeta:
+ rollup:
+ optional: true
+
+ '@rollup/rollup-android-arm-eabi@4.60.0':
+ resolution: {integrity: sha512-WOhNW9K8bR3kf4zLxbfg6Pxu2ybOUbB2AjMDHSQx86LIF4rH4Ft7vmMwNt0loO0eonglSNy4cpD3MKXXKQu0/A==}
+ cpu: [arm]
+ os: [android]
+
+ '@rollup/rollup-android-arm64@4.60.0':
+ resolution: {integrity: sha512-u6JHLll5QKRvjciE78bQXDmqRqNs5M/3GVqZeMwvmjaNODJih/WIrJlFVEihvV0MiYFmd+ZyPr9wxOVbPAG2Iw==}
+ cpu: [arm64]
+ os: [android]
+
+ '@rollup/rollup-darwin-arm64@4.60.0':
+ resolution: {integrity: sha512-qEF7CsKKzSRc20Ciu2Zw1wRrBz4g56F7r/vRwY430UPp/nt1x21Q/fpJ9N5l47WWvJlkNCPJz3QRVw008fi7yA==}
+ cpu: [arm64]
+ os: [darwin]
+
+ '@rollup/rollup-darwin-x64@4.60.0':
+ resolution: {integrity: sha512-WADYozJ4QCnXCH4wPB+3FuGmDPoFseVCUrANmA5LWwGmC6FL14BWC7pcq+FstOZv3baGX65tZ378uT6WG8ynTw==}
+ cpu: [x64]
+ os: [darwin]
+
+ '@rollup/rollup-freebsd-arm64@4.60.0':
+ resolution: {integrity: sha512-6b8wGHJlDrGeSE3aH5mGNHBjA0TTkxdoNHik5EkvPHCt351XnigA4pS7Wsj/Eo9Y8RBU6f35cjN9SYmCFBtzxw==}
+ cpu: [arm64]
+ os: [freebsd]
+
+ '@rollup/rollup-freebsd-x64@4.60.0':
+ resolution: {integrity: sha512-h25Ga0t4jaylMB8M/JKAyrvvfxGRjnPQIR8lnCayyzEjEOx2EJIlIiMbhpWxDRKGKF8jbNH01NnN663dH638mA==}
+ cpu: [x64]
+ os: [freebsd]
+
+ '@rollup/rollup-linux-arm-gnueabihf@4.60.0':
+ resolution: {integrity: sha512-RzeBwv0B3qtVBWtcuABtSuCzToo2IEAIQrcyB/b2zMvBWVbjo8bZDjACUpnaafaxhTw2W+imQbP2BD1usasK4g==}
+ cpu: [arm]
+ os: [linux]
+
+ '@rollup/rollup-linux-arm-musleabihf@4.60.0':
+ resolution: {integrity: sha512-Sf7zusNI2CIU1HLzuu9Tc5YGAHEZs5Lu7N1ssJG4Tkw6e0MEsN7NdjUDDfGNHy2IU+ENyWT+L2obgWiguWibWQ==}
+ cpu: [arm]
+ os: [linux]
+
+ '@rollup/rollup-linux-arm64-gnu@4.60.0':
+ resolution: {integrity: sha512-DX2x7CMcrJzsE91q7/O02IJQ5/aLkVtYFryqCjduJhUfGKG6yJV8hxaw8pZa93lLEpPTP/ohdN4wFz7yp/ry9A==}
+ cpu: [arm64]
+ os: [linux]
+
+ '@rollup/rollup-linux-arm64-musl@4.60.0':
+ resolution: {integrity: sha512-09EL+yFVbJZlhcQfShpswwRZ0Rg+z/CsSELFCnPt3iK+iqwGsI4zht3secj5vLEs957QvFFXnzAT0FFPIxSrkQ==}
+ cpu: [arm64]
+ os: [linux]
+
+ '@rollup/rollup-linux-loong64-gnu@4.60.0':
+ resolution: {integrity: sha512-i9IcCMPr3EXm8EQg5jnja0Zyc1iFxJjZWlb4wr7U2Wx/GrddOuEafxRdMPRYVaXjgbhvqalp6np07hN1w9kAKw==}
+ cpu: [loong64]
+ os: [linux]
+
+ '@rollup/rollup-linux-loong64-musl@4.60.0':
+ resolution: {integrity: sha512-DGzdJK9kyJ+B78MCkWeGnpXJ91tK/iKA6HwHxF4TAlPIY7GXEvMe8hBFRgdrR9Ly4qebR/7gfUs9y2IoaVEyog==}
+ cpu: [loong64]
+ os: [linux]
+
+ '@rollup/rollup-linux-ppc64-gnu@4.60.0':
+ resolution: {integrity: sha512-RwpnLsqC8qbS8z1H1AxBA1H6qknR4YpPR9w2XX0vo2Sz10miu57PkNcnHVaZkbqyw/kUWfKMI73jhmfi9BRMUQ==}
+ cpu: [ppc64]
+ os: [linux]
+
+ '@rollup/rollup-linux-ppc64-musl@4.60.0':
+ resolution: {integrity: sha512-Z8pPf54Ly3aqtdWC3G4rFigZgNvd+qJlOE52fmko3KST9SoGfAdSRCwyoyG05q1HrrAblLbk1/PSIV+80/pxLg==}
+ cpu: [ppc64]
+ os: [linux]
+
+ '@rollup/rollup-linux-riscv64-gnu@4.60.0':
+ resolution: {integrity: sha512-3a3qQustp3COCGvnP4SvrMHnPQ9d1vzCakQVRTliaz8cIp/wULGjiGpbcqrkv0WrHTEp8bQD/B3HBjzujVWLOA==}
+ cpu: [riscv64]
+ os: [linux]
+
+ '@rollup/rollup-linux-riscv64-musl@4.60.0':
+ resolution: {integrity: sha512-pjZDsVH/1VsghMJ2/kAaxt6dL0psT6ZexQVrijczOf+PeP2BUqTHYejk3l6TlPRydggINOeNRhvpLa0AYpCWSQ==}
+ cpu: [riscv64]
+ os: [linux]
+
+ '@rollup/rollup-linux-s390x-gnu@4.60.0':
+ resolution: {integrity: sha512-3ObQs0BhvPgiUVZrN7gqCSvmFuMWvWvsjG5ayJ3Lraqv+2KhOsp+pUbigqbeWqueGIsnn+09HBw27rJ+gYK4VQ==}
+ cpu: [s390x]
+ os: [linux]
+
+ '@rollup/rollup-linux-x64-gnu@4.60.0':
+ resolution: {integrity: sha512-EtylprDtQPdS5rXvAayrNDYoJhIz1/vzN2fEubo3yLE7tfAw+948dO0g4M0vkTVFhKojnF+n6C8bDNe+gDRdTg==}
+ cpu: [x64]
+ os: [linux]
+
+ '@rollup/rollup-linux-x64-musl@4.60.0':
+ resolution: {integrity: sha512-k09oiRCi/bHU9UVFqD17r3eJR9bn03TyKraCrlz5ULFJGdJGi7VOmm9jl44vOJvRJ6P7WuBi/s2A97LxxHGIdw==}
+ cpu: [x64]
+ os: [linux]
+
+ '@rollup/rollup-openbsd-x64@4.60.0':
+ resolution: {integrity: sha512-1o/0/pIhozoSaDJoDcec+IVLbnRtQmHwPV730+AOD29lHEEo4F5BEUB24H0OBdhbBBDwIOSuf7vgg0Ywxdfiiw==}
+ cpu: [x64]
+ os: [openbsd]
+
+ '@rollup/rollup-openharmony-arm64@4.60.0':
+ resolution: {integrity: sha512-pESDkos/PDzYwtyzB5p/UoNU/8fJo68vcXM9ZW2V0kjYayj1KaaUfi1NmTUTUpMn4UhU4gTuK8gIaFO4UGuMbA==}
+ cpu: [arm64]
+ os: [openharmony]
+
+ '@rollup/rollup-win32-arm64-msvc@4.60.0':
+ resolution: {integrity: sha512-hj1wFStD7B1YBeYmvY+lWXZ7ey73YGPcViMShYikqKT1GtstIKQAtfUI6yrzPjAy/O7pO0VLXGmUVWXQMaYgTQ==}
+ cpu: [arm64]
+ os: [win32]
+
+ '@rollup/rollup-win32-ia32-msvc@4.60.0':
+ resolution: {integrity: sha512-SyaIPFoxmUPlNDq5EHkTbiKzmSEmq/gOYFI/3HHJ8iS/v1mbugVa7dXUzcJGQfoytp9DJFLhHH4U3/eTy2Bq4w==}
+ cpu: [ia32]
+ os: [win32]
+
+ '@rollup/rollup-win32-x64-gnu@4.60.0':
+ resolution: {integrity: sha512-RdcryEfzZr+lAr5kRm2ucN9aVlCCa2QNq4hXelZxb8GG0NJSazq44Z3PCCc8wISRuCVnGs0lQJVX5Vp6fKA+IA==}
+ cpu: [x64]
+ os: [win32]
+
+ '@rollup/rollup-win32-x64-msvc@4.60.0':
+ resolution: {integrity: sha512-PrsWNQ8BuE00O3Xsx3ALh2Df8fAj9+cvvX9AIA6o4KpATR98c9mud4XtDWVvsEuyia5U4tVSTKygawyJkjm60w==}
+ cpu: [x64]
+ os: [win32]
+
+ '@shikijs/core@4.0.2':
+ resolution: {integrity: sha512-hxT0YF4ExEqB8G/qFdtJvpmHXBYJ2lWW7qTHDarVkIudPFE6iCIrqdgWxGn5s+ppkGXI0aEGlibI0PAyzP3zlw==}
+ engines: {node: '>=20'}
+
+ '@shikijs/engine-javascript@4.0.2':
+ resolution: {integrity: sha512-7PW0Nm49DcoUIQEXlJhNNBHyoGMjalRETTCcjMqEaMoJRLljy1Bi/EGV3/qLBgLKQejdspiiYuHGQW6dX94Nag==}
+ engines: {node: '>=20'}
+
+ '@shikijs/engine-oniguruma@4.0.2':
+ resolution: {integrity: sha512-UpCB9Y2sUKlS9z8juFSKz7ZtysmeXCgnRF0dlhXBkmQnek7lAToPte8DkxmEYGNTMii72zU/lyXiCB6StuZeJg==}
+ engines: {node: '>=20'}
+
+ '@shikijs/langs@4.0.2':
+ resolution: {integrity: sha512-KaXby5dvoeuZzN0rYQiPMjFoUrz4hgwIE+D6Du9owcHcl6/g16/yT5BQxSW5cGt2MZBz6Hl0YuRqf12omRfUUg==}
+ engines: {node: '>=20'}
+
+ '@shikijs/primitive@4.0.2':
+ resolution: {integrity: sha512-M6UMPrSa3fN5ayeJwFVl9qWofl273wtK1VG8ySDZ1mQBfhCpdd8nEx7nPZ/tk7k+TYcpqBZzj/AnwxT9lO+HJw==}
+ engines: {node: '>=20'}
+
+ '@shikijs/themes@4.0.2':
+ resolution: {integrity: sha512-mjCafwt8lJJaVSsQvNVrJumbnnj1RI8jbUKrPKgE6E3OvQKxnuRoBaYC51H4IGHePsGN/QtALglWBU7DoKDFnA==}
+ engines: {node: '>=20'}
+
+ '@shikijs/types@4.0.2':
+ resolution: {integrity: sha512-qzbeRooUTPnLE+sHD/Z8DStmaDgnbbc/pMrU203950aRqjX/6AFHeDYT+j00y2lPdz0ywJKx7o/7qnqTivtlXg==}
+ engines: {node: '>=20'}
+
+ '@shikijs/vscode-textmate@10.0.2':
+ resolution: {integrity: sha512-83yeghZ2xxin3Nj8z1NMd/NCuca+gsYXswywDy5bHvwlWL8tpTQmzGeUuHd9FC3E/SBEMvzJRwWEOz5gGes9Qg==}
+
+ '@simple-libs/child-process-utils@1.0.2':
+ resolution: {integrity: sha512-/4R8QKnd/8agJynkNdJmNw2MBxuFTRcNFnE5Sg/G+jkSsV8/UBgULMzhizWWW42p8L5H7flImV2ATi79Ove2Tw==}
+ engines: {node: '>=18'}
+
+ '@simple-libs/stream-utils@1.2.0':
+ resolution: {integrity: sha512-KxXvfapcixpz6rVEB6HPjOUZT22yN6v0vI0urQSk1L8MlEWPDFCZkhw2xmkyoTGYeFw7tWTZd7e3lVzRZRN/EA==}
+ engines: {node: '>=18'}
+
+ '@standard-schema/spec@1.1.0':
+ resolution: {integrity: sha512-l2aFy5jALhniG5HgqrD6jXLi/rUWrKvqN/qJx6yoJsgKhblVd+iqqU4RCXavm/jPityDo5TCvKMnpjKnOriy0w==}
+
+ '@tailwindcss/node@4.2.2':
+ resolution: {integrity: sha512-pXS+wJ2gZpVXqFaUEjojq7jzMpTGf8rU6ipJz5ovJV6PUGmlJ+jvIwGrzdHdQ80Sg+wmQxUFuoW1UAAwHNEdFA==}
+
+ '@tailwindcss/oxide-android-arm64@4.2.2':
+ resolution: {integrity: sha512-dXGR1n+P3B6748jZO/SvHZq7qBOqqzQ+yFrXpoOWWALWndF9MoSKAT3Q0fYgAzYzGhxNYOoysRvYlpixRBBoDg==}
+ engines: {node: '>= 20'}
+ cpu: [arm64]
+ os: [android]
+
+ '@tailwindcss/oxide-darwin-arm64@4.2.2':
+ resolution: {integrity: sha512-iq9Qjr6knfMpZHj55/37ouZeykwbDqF21gPFtfnhCCKGDcPI/21FKC9XdMO/XyBM7qKORx6UIhGgg6jLl7BZlg==}
+ engines: {node: '>= 20'}
+ cpu: [arm64]
+ os: [darwin]
+
+ '@tailwindcss/oxide-darwin-x64@4.2.2':
+ resolution: {integrity: sha512-BlR+2c3nzc8f2G639LpL89YY4bdcIdUmiOOkv2GQv4/4M0vJlpXEa0JXNHhCHU7VWOKWT/CjqHdTP8aUuDJkuw==}
+ engines: {node: '>= 20'}
+ cpu: [x64]
+ os: [darwin]
+
+ '@tailwindcss/oxide-freebsd-x64@4.2.2':
+ resolution: {integrity: sha512-YUqUgrGMSu2CDO82hzlQ5qSb5xmx3RUrke/QgnoEx7KvmRJHQuZHZmZTLSuuHwFf0DJPybFMXMYf+WJdxHy/nQ==}
+ engines: {node: '>= 20'}
+ cpu: [x64]
+ os: [freebsd]
+
+ '@tailwindcss/oxide-linux-arm-gnueabihf@4.2.2':
+ resolution: {integrity: sha512-FPdhvsW6g06T9BWT0qTwiVZYE2WIFo2dY5aCSpjG/S/u1tby+wXoslXS0kl3/KXnULlLr1E3NPRRw0g7t2kgaQ==}
+ engines: {node: '>= 20'}
+ cpu: [arm]
+ os: [linux]
+
+ '@tailwindcss/oxide-linux-arm64-gnu@4.2.2':
+ resolution: {integrity: sha512-4og1V+ftEPXGttOO7eCmW7VICmzzJWgMx+QXAJRAhjrSjumCwWqMfkDrNu1LXEQzNAwz28NCUpucgQPrR4S2yw==}
+ engines: {node: '>= 20'}
+ cpu: [arm64]
+ os: [linux]
+
+ '@tailwindcss/oxide-linux-arm64-musl@4.2.2':
+ resolution: {integrity: sha512-oCfG/mS+/+XRlwNjnsNLVwnMWYH7tn/kYPsNPh+JSOMlnt93mYNCKHYzylRhI51X+TbR+ufNhhKKzm6QkqX8ag==}
+ engines: {node: '>= 20'}
+ cpu: [arm64]
+ os: [linux]
+
+ '@tailwindcss/oxide-linux-x64-gnu@4.2.2':
+ resolution: {integrity: sha512-rTAGAkDgqbXHNp/xW0iugLVmX62wOp2PoE39BTCGKjv3Iocf6AFbRP/wZT/kuCxC9QBh9Pu8XPkv/zCZB2mcMg==}
+ engines: {node: '>= 20'}
+ cpu: [x64]
+ os: [linux]
+
+ '@tailwindcss/oxide-linux-x64-musl@4.2.2':
+ resolution: {integrity: sha512-XW3t3qwbIwiSyRCggeO2zxe3KWaEbM0/kW9e8+0XpBgyKU4ATYzcVSMKteZJ1iukJ3HgHBjbg9P5YPRCVUxlnQ==}
+ engines: {node: '>= 20'}
+ cpu: [x64]
+ os: [linux]
+
+ '@tailwindcss/oxide-wasm32-wasi@4.2.2':
+ resolution: {integrity: sha512-eKSztKsmEsn1O5lJ4ZAfyn41NfG7vzCg496YiGtMDV86jz1q/irhms5O0VrY6ZwTUkFy/EKG3RfWgxSI3VbZ8Q==}
+ engines: {node: '>=14.0.0'}
+ cpu: [wasm32]
+ bundledDependencies:
+ - '@napi-rs/wasm-runtime'
+ - '@emnapi/core'
+ - '@emnapi/runtime'
+ - '@tybys/wasm-util'
+ - '@emnapi/wasi-threads'
+ - tslib
+
+ '@tailwindcss/oxide-win32-arm64-msvc@4.2.2':
+ resolution: {integrity: sha512-qPmaQM4iKu5mxpsrWZMOZRgZv1tOZpUm+zdhhQP0VhJfyGGO3aUKdbh3gDZc/dPLQwW4eSqWGrrcWNBZWUWaXQ==}
+ engines: {node: '>= 20'}
+ cpu: [arm64]
+ os: [win32]
+
+ '@tailwindcss/oxide-win32-x64-msvc@4.2.2':
+ resolution: {integrity: sha512-1T/37VvI7WyH66b+vqHj/cLwnCxt7Qt3WFu5Q8hk65aOvlwAhs7rAp1VkulBJw/N4tMirXjVnylTR72uI0HGcA==}
+ engines: {node: '>= 20'}
+ cpu: [x64]
+ os: [win32]
+
+ '@tailwindcss/oxide@4.2.2':
+ resolution: {integrity: sha512-qEUA07+E5kehxYp9BVMpq9E8vnJuBHfJEC0vPC5e7iL/hw7HR61aDKoVoKzrG+QKp56vhNZe4qwkRmMC0zDLvg==}
+ engines: {node: '>= 20'}
+
+ '@tailwindcss/vite@4.2.2':
+ resolution: {integrity: sha512-mEiF5HO1QqCLXoNEfXVA1Tzo+cYsrqV7w9Juj2wdUFyW07JRenqMG225MvPwr3ZD9N1bFQj46X7r33iHxLUW0w==}
+ peerDependencies:
+ vite: ^5.2.0 || ^6 || ^7 || ^8
+
+ '@testing-library/jest-dom@6.9.1':
+ resolution: {integrity: sha512-zIcONa+hVtVSSep9UT3jZ5rizo2BsxgyDYU7WFD5eICBE7no3881HGeb/QkGfsJs6JTkY1aQhT7rIPC7e+0nnA==}
+ engines: {node: '>=14', npm: '>=6', yarn: '>=1'}
+
+ '@types/chai@5.2.3':
+ resolution: {integrity: sha512-Mw558oeA9fFbv65/y4mHtXDs9bPnFMZAL/jxdPFUpOHHIXX91mcgEHbS5Lahr+pwZFR8A7GQleRWeI6cGFC2UA==}
+
+ '@types/concat-stream@1.6.1':
+ resolution: {integrity: sha512-eHE4cQPoj6ngxBZMvVf6Hw7Mh4jMW4U9lpGmS5GBPB9RYxlFg+CHaVN7ErNY4W9XfLIEn20b4VDYaIrbq0q4uA==}
+
+ '@types/debug@4.1.13':
+ resolution: {integrity: sha512-KSVgmQmzMwPlmtljOomayoR89W4FynCAi3E8PPs7vmDVPe84hT+vGPKkJfThkmXs0x0jAaa9U8uW8bbfyS2fWw==}
+
+ '@types/deep-eql@4.0.2':
+ resolution: {integrity: sha512-c9h9dVVMigMPc4bwTvC5dxqtqJZwQPePsWjPlpSOnojbor6pGqdk541lfA7AqFQr5pB1BRdq0juY9db81BwyFw==}
+
+ '@types/estree@1.0.8':
+ resolution: {integrity: sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==}
+
+ '@types/form-data@0.0.33':
+ resolution: {integrity: sha512-8BSvG1kGm83cyJITQMZSulnl6QV8jqAGreJsc5tPu1Jq0vTSOiY/k24Wx82JRpWwZSqrala6sd5rWi6aNXvqcw==}
+
+ '@types/hast@3.0.4':
+ resolution: {integrity: sha512-WPs+bbQw5aCj+x6laNGWLH3wviHtoCv/P3+otBhbOhJgG8qtpdAMlTCxLtsTWA7LH1Oh/bFCHsBn0TPS5m30EQ==}
+
+ '@types/mdast@4.0.4':
+ resolution: {integrity: sha512-kGaNbPh1k7AFzgpud/gMdvIm5xuECykRR+JnWKQno9TAXVa6WIVCGTPvYGekIDL4uwCZQSYbUxNBSb1aUo79oA==}
+
+ '@types/ms@2.1.0':
+ resolution: {integrity: sha512-GsCCIZDE/p3i96vtEqx+7dBUGXrc7zeSK3wwPHIaRThS+9OhWIXRqzs4d6k1SVU8g91DrNRWxWUGhp5KXQb2VA==}
+
+ '@types/nlcst@2.0.3':
+ resolution: {integrity: sha512-vSYNSDe6Ix3q+6Z7ri9lyWqgGhJTmzRjZRqyq15N0Z/1/UnVsno9G/N40NBijoYx2seFDIl0+B2mgAb9mezUCA==}
+
+ '@types/node@10.17.60':
+ resolution: {integrity: sha512-F0KIgDJfy2nA3zMLmWGKxcH2ZVEtCZXHHdOQs2gSaQ27+lNeEfGxzkIw90aXswATX7AZ33tahPbzy6KAfUreVw==}
+
+ '@types/node@25.5.0':
+ resolution: {integrity: sha512-jp2P3tQMSxWugkCUKLRPVUpGaL5MVFwF8RDuSRztfwgN1wmqJeMSbKlnEtQqU8UrhTmzEmZdu2I6v2dpp7XIxw==}
+
+ '@types/node@8.10.66':
+ resolution: {integrity: sha512-tktOkFUA4kXx2hhhrB8bIFb5TbwzS4uOhKEmwiD+NoiL0qtP2OQ9mFldbgD4dV1djrlBYP6eBuQZiWjuHUpqFw==}
+
+ '@types/qs@6.15.0':
+ resolution: {integrity: sha512-JawvT8iBVWpzTrz3EGw9BTQFg3BQNmwERdKE22vlTxawwtbyUSlMppvZYKLZzB5zgACXdXxbD3m1bXaMqP/9ow==}
+
+ '@types/unist@3.0.3':
+ resolution: {integrity: sha512-ko/gIFJRv177XgZsZcBwnqJN5x/Gien8qNOn0D5bQU/zAzVf9Zt3BlcUiLqhV9y4ARk0GbT3tnUiPNgnTXzc/Q==}
+
+ '@types/yauzl@2.10.3':
+ resolution: {integrity: sha512-oJoftv0LSuaDZE3Le4DbKX+KS9G36NzOeSap90UIK0yMA/NhKJhqlSGtNDORNRaIbQfzjXDrQa0ytJ6mNRGz/Q==}
+
+ '@ungap/structured-clone@1.3.0':
+ resolution: {integrity: sha512-WmoN8qaIAo7WTYWbAZuG8PYEhn5fkz7dZrqTBZ7dtt//lL2Gwms1IcnQ5yHqjDfX8Ft5j4YzDM23f87zBfDe9g==}
+
+ '@vitest/coverage-v8@4.1.1':
+ resolution: {integrity: sha512-nZ4RWwGCoGOQRMmU/Q9wlUY540RVRxJZ9lxFsFfy0QV7Zmo5VVBhB6Sl9Xa0KIp2iIs3zWfPlo9LcY1iqbpzCw==}
+ peerDependencies:
+ '@vitest/browser': 4.1.1
+ vitest: 4.1.1
+ peerDependenciesMeta:
+ '@vitest/browser':
+ optional: true
+
+ '@vitest/expect@4.1.1':
+ resolution: {integrity: sha512-xAV0fqBTk44Rn6SjJReEQkHP3RrqbJo6JQ4zZ7/uVOiJZRarBtblzrOfFIZeYUrukp2YD6snZG6IBqhOoHTm+A==}
+
+ '@vitest/mocker@4.1.1':
+ resolution: {integrity: sha512-h3BOylsfsCLPeceuCPAAJ+BvNwSENgJa4hXoXu4im0bs9Lyp4URc4JYK4pWLZ4pG/UQn7AT92K6IByi6rE6g3A==}
+ peerDependencies:
+ msw: ^2.4.9
+ vite: ^6.0.0 || ^7.0.0 || ^8.0.0
+ peerDependenciesMeta:
+ msw:
+ optional: true
+ vite:
+ optional: true
+
+ '@vitest/pretty-format@4.1.1':
+ resolution: {integrity: sha512-GM+TEQN5WhOygr1lp7skeVjdLPqqWMHsfzXrcHAqZJi/lIVh63H0kaRCY8MDhNWikx19zBUK8ceaLB7X5AH9NQ==}
+
+ '@vitest/runner@4.1.1':
+ resolution: {integrity: sha512-f7+FPy75vN91QGWsITueq0gedwUZy1fLtHOCMeQpjs8jTekAHeKP80zfDEnhrleviLHzVSDXIWuCIOFn3D3f8A==}
+
+ '@vitest/snapshot@4.1.1':
+ resolution: {integrity: sha512-kMVSgcegWV2FibXEx9p9WIKgje58lcTbXgnJixfcg15iK8nzCXhmalL0ZLtTWLW9PH1+1NEDShiFFedB3tEgWg==}
+
+ '@vitest/spy@4.1.1':
+ resolution: {integrity: sha512-6Ti/KT5OVaiupdIZEuZN7l3CZcR0cxnxt70Z0//3CtwgObwA6jZhmVBA3yrXSVN3gmwjgd7oDNLlsXz526gpRA==}
+
+ '@vitest/ui@4.1.1':
+ resolution: {integrity: sha512-k0qNVLmCISxoGWvdhOeynlZVrfjx7Xjp95kIptN0fZYyONCgVcKIPn53MpFZ7S+fO6YdKNhgIfl0nu92Q0CCOg==}
+ peerDependencies:
+ vitest: 4.1.1
+
+ '@vitest/utils@4.1.1':
+ resolution: {integrity: sha512-cNxAlaB3sHoCdL6pj6yyUXv9Gry1NHNg0kFTXdvSIZXLHsqKH7chiWOkwJ5s5+d/oMwcoG9T0bKU38JZWKusrQ==}
+
+ '@volar/kit@2.4.28':
+ resolution: {integrity: sha512-cKX4vK9dtZvDRaAzeoUdaAJEew6IdxHNCRrdp5Kvcl6zZOqb6jTOfk3kXkIkG3T7oTFXguEMt5+9ptyqYR84Pg==}
+ peerDependencies:
+ typescript: '*'
+
+ '@volar/language-core@2.4.28':
+ resolution: {integrity: sha512-w4qhIJ8ZSitgLAkVay6AbcnC7gP3glYM3fYwKV3srj8m494E3xtrCv6E+bWviiK/8hs6e6t1ij1s2Endql7vzQ==}
+
+ '@volar/language-server@2.4.28':
+ resolution: {integrity: sha512-NqcLnE5gERKuS4PUFwlhMxf6vqYo7hXtbMFbViXcbVkbZ905AIVWhnSo0ZNBC2V127H1/2zP7RvVOVnyITFfBw==}
+
+ '@volar/language-service@2.4.28':
+ resolution: {integrity: sha512-Rh/wYCZJrI5vCwMk9xyw/Z+MsWxlJY1rmMZPsxUoJKfzIRjS/NF1NmnuEcrMbEVGja00aVpCsInJfixQTMdvLw==}
+
+ '@volar/source-map@2.4.28':
+ resolution: {integrity: sha512-yX2BDBqJkRXfKw8my8VarTyjv48QwxdJtvRgUpNE5erCsgEUdI2DsLbpa+rOQVAJYshY99szEcRDmyHbF10ggQ==}
+
+ '@volar/typescript@2.4.28':
+ resolution: {integrity: sha512-Ja6yvWrbis2QtN4ClAKreeUZPVYMARDYZl9LMEv1iQ1QdepB6wn0jTRxA9MftYmYa4DQ4k/DaSZpFPUfxl8giw==}
+
+ '@vscode/emmet-helper@2.11.0':
+ resolution: {integrity: sha512-QLxjQR3imPZPQltfbWRnHU6JecWTF1QSWhx3GAKQpslx7y3Dp6sIIXhKjiUJ/BR9FX8PVthjr9PD6pNwOJfAzw==}
+
+ '@vscode/l10n@0.0.18':
+ resolution: {integrity: sha512-KYSIHVmslkaCDyw013pphY+d7x1qV8IZupYfeIfzNA+nsaWHbn5uPuQRvdRFsa9zFzGeudPuoGoZ1Op4jrJXIQ==}
+
+ acorn@8.16.0:
+ resolution: {integrity: sha512-UVJyE9MttOsBQIDKw1skb9nAwQuR5wuGD3+82K6JgJlm/Y+KI92oNsMNGZCYdDsVtRHSak0pcV5Dno5+4jh9sw==}
+ engines: {node: '>=0.4.0'}
+ hasBin: true
+
+ ajv-draft-04@1.0.0:
+ resolution: {integrity: sha512-mv00Te6nmYbRp5DCwclxtt7yV/joXJPGS7nM+97GdxvuttCOfgI3K4U25zboyeX0O+myI8ERluxQe5wljMmVIw==}
+ peerDependencies:
+ ajv: ^8.5.0
+ peerDependenciesMeta:
+ ajv:
+ optional: true
+
+ ajv@8.18.0:
+ resolution: {integrity: sha512-PlXPeEWMXMZ7sPYOHqmDyCJzcfNrUr3fGNKtezX14ykXOEIvyK81d+qydx89KY5O71FKMPaQ2vBfBFI5NHR63A==}
+
+ ansi-regex@5.0.1:
+ resolution: {integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==}
+ engines: {node: '>=8'}
+
+ ansi-styles@4.3.0:
+ resolution: {integrity: sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==}
+ engines: {node: '>=8'}
+
+ anymatch@3.1.3:
+ resolution: {integrity: sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==}
+ engines: {node: '>= 8'}
+
+ argparse@2.0.1:
+ resolution: {integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==}
+
+ aria-query@5.3.2:
+ resolution: {integrity: sha512-COROpnaoap1E2F000S62r6A60uHZnmlvomhfyT2DlTcrY1OrBKn2UhH7qn5wTC9zMvD0AY7csdPSNwKP+7WiQw==}
+ engines: {node: '>= 0.4'}
+
+ array-ify@1.0.0:
+ resolution: {integrity: sha512-c5AMf34bKdvPhQ7tBGhqkgKNUzMr4WUs+WDtC2ZUGOUncbxKMTvqxYctiseW3+L4bA8ec+GcZ6/A/FW4m8ukng==}
+
+ array-iterate@2.0.1:
+ resolution: {integrity: sha512-I1jXZMjAgCMmxT4qxXfPXa6SthSoE8h6gkSI9BGGNv8mP8G/v0blc+qFnZu6K42vTOiuME596QaLO0TP3Lk0xg==}
+
+ asap@2.0.6:
+ resolution: {integrity: sha512-BSHWgDSAiKs50o2Re8ppvp3seVHXSRM44cdSsT9FfNEUUZLOGWVCsiWaRPWM1Znn+mqZ1OfVZ3z3DWEzSp7hRA==}
+
+ assertion-error@2.0.1:
+ resolution: {integrity: sha512-Izi8RQcffqCeNVgFigKli1ssklIbpHnCYc6AknXGYoB6grJqyeby7jv12JUQgmTAnIDnbck1uxksT4dzN3PWBA==}
+ engines: {node: '>=12'}
+
+ ast-v8-to-istanbul@1.0.0:
+ resolution: {integrity: sha512-1fSfIwuDICFA4LKkCzRPO7F0hzFf0B7+Xqrl27ynQaa+Rh0e1Es0v6kWHPott3lU10AyAr7oKHa65OppjLn3Rg==}
+
+ astro-icon@1.1.5:
+ resolution: {integrity: sha512-CJYS5nWOw9jz4RpGWmzNQY7D0y2ZZacH7atL2K9DeJXJVaz7/5WrxeyIxO8KASk1jCM96Q4LjRx/F3R+InjJrw==}
+
+ astro@6.0.8:
+ resolution: {integrity: sha512-DCPeb8GKOoFWh+8whB7Qi/kKWD/6NcQ9nd1QVNzJFxgHkea3WYrNroQRq4whmBdjhkYPTLS/1gmUAl2iA2Es2g==}
+ engines: {node: '>=22.12.0', npm: '>=9.6.5', pnpm: '>=7.1.0'}
+ hasBin: true
+
+ asynckit@0.4.0:
+ resolution: {integrity: sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==}
+
+ autoprefixer@10.4.27:
+ resolution: {integrity: sha512-NP9APE+tO+LuJGn7/9+cohklunJsXWiaWEfV3si4Gi/XHDwVNgkwr1J3RQYFIvPy76GmJ9/bW8vyoU1LcxwKHA==}
+ engines: {node: ^10 || ^12 || >=14}
+ hasBin: true
+ peerDependencies:
+ postcss: ^8.1.0
+
+ axobject-query@4.1.0:
+ resolution: {integrity: sha512-qIj0G9wZbMGNLjLmg1PT6v2mE9AH2zlnADJD/2tC6E00hgmhUOfEB6greHPAfLRSufHqROIUTkw6E+M3lH0PTQ==}
+ engines: {node: '>= 0.4'}
+
+ bail@2.0.2:
+ resolution: {integrity: sha512-0xO6mYd7JB2YesxDKplafRpsiOzPt9V02ddPCLbY1xYGPOX24NTyN50qnUxgCPcSoYMhKpAuBTjQoRZCAkUDRw==}
+
+ baseline-browser-mapping@2.10.10:
+ resolution: {integrity: sha512-sUoJ3IMxx4AyRqO4MLeHlnGDkyXRoUG0/AI9fjK+vS72ekpV0yWVY7O0BVjmBcRtkNcsAO2QDZ4tdKKGoI6YaQ==}
+ engines: {node: '>=6.0.0'}
+ hasBin: true
+
+ bidi-js@1.0.3:
+ resolution: {integrity: sha512-RKshQI1R3YQ+n9YJz2QQ147P66ELpa1FQEg20Dk8oW9t2KgLbpDLLp9aGZ7y8WHSshDknG0bknqGw5/tyCs5tw==}
+
+ boolbase@1.0.0:
+ resolution: {integrity: sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==}
+
+ browserslist@4.28.1:
+ resolution: {integrity: sha512-ZC5Bd0LgJXgwGqUknZY/vkUQ04r8NXnJZ3yYi4vDmSiZmC/pdSN0NbNRPxZpbtO4uAfDUAFffO8IZoM3Gj8IkA==}
+ engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7}
+ hasBin: true
+
+ buffer-crc32@0.2.13:
+ resolution: {integrity: sha512-VO9Ht/+p3SN7SKWqcrgEzjGbRSJYTx+Q1pTQC0wrWqHx0vpJraQ6GtHx8tvcg1rlK1byhU5gccxgOgj7B0TDkQ==}
+
+ buffer-from@1.1.2:
+ resolution: {integrity: sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==}
+
+ call-bind-apply-helpers@1.0.2:
+ resolution: {integrity: sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==}
+ engines: {node: '>= 0.4'}
+
+ call-bound@1.0.4:
+ resolution: {integrity: sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg==}
+ engines: {node: '>= 0.4'}
+
+ callsites@3.1.0:
+ resolution: {integrity: sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==}
+ engines: {node: '>=6'}
+
+ caniuse-lite@1.0.30001781:
+ resolution: {integrity: sha512-RdwNCyMsNBftLjW6w01z8bKEvT6e/5tpPVEgtn22TiLGlstHOVecsX2KHFkD5e/vRnIE4EGzpuIODb3mtswtkw==}
+
+ caseless@0.12.0:
+ resolution: {integrity: sha512-4tYFyifaFfGacoiObjJegolkwSU4xQNGbVgUiNYVUxbQ2x2lUsFvY4hVgVzGiIe6WLOPqycWXA40l+PWsxthUw==}
+
+ ccount@2.0.1:
+ resolution: {integrity: sha512-eyrF0jiFpY+3drT6383f1qhkbGsLSifNAjA61IUjZjmLCWjItY6LB9ft9YhoDgwfmclB2zhu51Lc7+95b8NRAg==}
+
+ chai@6.2.2:
+ resolution: {integrity: sha512-NUPRluOfOiTKBKvWPtSD4PhFvWCqOi0BGStNWs57X9js7XGTprSmFoz5F0tWhR4WPjNeR9jXqdC7/UpSJTnlRg==}
+ engines: {node: '>=18'}
+
+ character-entities-html4@2.1.0:
+ resolution: {integrity: sha512-1v7fgQRj6hnSwFpq1Eu0ynr/CDEw0rXo2B61qXrLNdHZmPKgb7fqS1a2JwF0rISo9q77jDI8VMEHoApn8qDoZA==}
+
+ character-entities-legacy@3.0.0:
+ resolution: {integrity: sha512-RpPp0asT/6ufRm//AJVwpViZbGM/MkjQFxJccQRHmISF/22NBtsHqAWmL+/pmkPWoIUJdWyeVleTl1wydHATVQ==}
+
+ character-entities@2.0.2:
+ resolution: {integrity: sha512-shx7oQ0Awen/BRIdkjkvz54PnEEI/EjwXDSIZp86/KKdbafHh1Df/RYGBhn4hbe2+uKC9FnT5UCEdyPz3ai9hQ==}
+
+ cheerio-select@2.1.0:
+ resolution: {integrity: sha512-9v9kG0LvzrlcungtnJtpGNxY+fzECQKhK4EGJX2vByejiMX84MFNQw4UxPJl3bFbTMw+Dfs37XaIkCwTZfLh4g==}
+
+ cheerio@1.2.0:
+ resolution: {integrity: sha512-WDrybc/gKFpTYQutKIK6UvfcuxijIZfMfXaYm8NMsPQxSYvf+13fXUJ4rztGGbJcBQ/GF55gvrZ0Bc0bj/mqvg==}
+ engines: {node: '>=20.18.1'}
+
+ chokidar@4.0.3:
+ resolution: {integrity: sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA==}
+ engines: {node: '>= 14.16.0'}
+
+ chokidar@5.0.0:
+ resolution: {integrity: sha512-TQMmc3w+5AxjpL8iIiwebF73dRDF4fBIieAqGn9RGCWaEVwQ6Fb2cGe31Yns0RRIzii5goJ1Y7xbMwo1TxMplw==}
+ engines: {node: '>= 20.19.0'}
+
+ chownr@3.0.0:
+ resolution: {integrity: sha512-+IxzY9BZOQd/XuYPRmrvEVjF/nqj5kgT4kEq7VofrDoM1MxoRjEWkrCC3EtLi59TVawxTAn+orJwFQcrqEN1+g==}
+ engines: {node: '>=18'}
+
+ ci-info@4.4.0:
+ resolution: {integrity: sha512-77PSwercCZU2Fc4sX94eF8k8Pxte6JAwL4/ICZLFjJLqegs7kCuAsqqj/70NQF6TvDpgFjkubQB2FW2ZZddvQg==}
+ engines: {node: '>=8'}
+
+ cliui@8.0.1:
+ resolution: {integrity: sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==}
+ engines: {node: '>=12'}
+
+ clsx@2.1.1:
+ resolution: {integrity: sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA==}
+ engines: {node: '>=6'}
+
+ color-convert@2.0.1:
+ resolution: {integrity: sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==}
+ engines: {node: '>=7.0.0'}
+
+ color-name@1.1.4:
+ resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==}
+
+ combined-stream@1.0.8:
+ resolution: {integrity: sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==}
+ engines: {node: '>= 0.8'}
+
+ comma-separated-tokens@2.0.3:
+ resolution: {integrity: sha512-Fu4hJdvzeylCfQPp9SGWidpzrMs7tTrlu6Vb8XGaRGck8QSNZJJp538Wrb60Lax4fPwR64ViY468OIUTbRlGZg==}
+
+ commander@11.1.0:
+ resolution: {integrity: sha512-yPVavfyCcRhmorC7rWlkHn15b4wDVgVmBA7kV4QVBsF7kv/9TKJAbAXVTxvTnwP8HHKjRCJDClKbciiYS7p0DQ==}
+ engines: {node: '>=16'}
+
+ commander@7.2.0:
+ resolution: {integrity: sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw==}
+ engines: {node: '>= 10'}
+
+ common-ancestor-path@2.0.0:
+ resolution: {integrity: sha512-dnN3ibLeoRf2HNC+OlCiNc5d2zxbLJXOtiZUudNFSXZrNSydxcCsSpRzXwfu7BBWCIfHPw+xTayeBvJCP/D8Ng==}
+ engines: {node: '>= 18'}
+
+ compare-func@2.0.0:
+ resolution: {integrity: sha512-zHig5N+tPWARooBnb0Zx1MFcdfpyJrfTJ3Y5L+IFvUm8rM74hHz66z0gw0x4tijh5CorKkKUCnW82R2vmpeCRA==}
+
+ concat-stream@1.6.2:
+ resolution: {integrity: sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw==}
+ engines: {'0': node >= 0.8}
+
+ confbox@0.1.8:
+ resolution: {integrity: sha512-RMtmw0iFkeR4YV+fUOSucriAQNb9g8zFR52MWCtl+cCZOFRNL6zeB395vPzFhEjjn4fMxXudmELnl/KF/WrK6w==}
+
+ confbox@0.2.4:
+ resolution: {integrity: sha512-ysOGlgTFbN2/Y6Cg3Iye8YKulHw+R2fNXHrgSmXISQdMnomY6eNDprVdW9R5xBguEqI954+S6709UyiO7B+6OQ==}
+
+ conventional-changelog-angular@8.3.0:
+ resolution: {integrity: sha512-DOuBwYSqWzfwuRByY9O4oOIvDlkUCTDzfbOgcSbkY+imXXj+4tmrEFao3K+FxemClYfYnZzsvudbwrhje9VHDA==}
+ engines: {node: '>=18'}
+
+ conventional-changelog-conventionalcommits@9.3.0:
+ resolution: {integrity: sha512-kYFx6gAyjSIMwNtASkI3ZE99U1fuVDJr0yTYgVy+I2QG46zNZfl2her+0+eoviG82c5WQvW1jMt1eOQTeJLodA==}
+ engines: {node: '>=18'}
+
+ conventional-commits-parser@6.3.0:
+ resolution: {integrity: sha512-RfOq/Cqy9xV9bOA8N+ZH6DlrDR+5S3Mi0B5kACEjESpE+AviIpAptx9a9cFpWCCvgRtWT+0BbUw+e1BZfts9jg==}
+ engines: {node: '>=18'}
+ hasBin: true
+
+ convert-source-map@2.0.0:
+ resolution: {integrity: sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==}
+
+ cookie-es@1.2.2:
+ resolution: {integrity: sha512-+W7VmiVINB+ywl1HGXJXmrqkOhpKrIiVZV6tQuV54ZyQC7MMuBt81Vc336GMLoHBq5hV/F9eXgt5Mnx0Rha5Fg==}
+
+ cookie@1.1.1:
+ resolution: {integrity: sha512-ei8Aos7ja0weRpFzJnEA9UHJ/7XQmqglbRwnf2ATjcB9Wq874VKH9kfjjirM6UhU2/E5fFYadylyhFldcqSidQ==}
+ engines: {node: '>=18'}
+
+ core-util-is@1.0.3:
+ resolution: {integrity: sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==}
+
+ cosmiconfig-typescript-loader@6.2.0:
+ resolution: {integrity: sha512-GEN39v7TgdxgIoNcdkRE3uiAzQt3UXLyHbRHD6YoL048XAeOomyxaP+Hh/+2C6C2wYjxJ2onhJcsQp+L4YEkVQ==}
+ engines: {node: '>=v18'}
+ peerDependencies:
+ '@types/node': '*'
+ cosmiconfig: '>=9'
+ typescript: '>=5'
+
+ cosmiconfig@9.0.1:
+ resolution: {integrity: sha512-hr4ihw+DBqcvrsEDioRO31Z17x71pUYoNe/4h6Z0wB72p7MU7/9gH8Q3s12NFhHPfYBBOV3qyfUxmr/Yn3shnQ==}
+ engines: {node: '>=14'}
+ peerDependencies:
+ typescript: '>=4.9.5'
+ peerDependenciesMeta:
+ typescript:
+ optional: true
+
+ crossws@0.3.5:
+ resolution: {integrity: sha512-ojKiDvcmByhwa8YYqbQI/hg7MEU0NC03+pSdEq4ZUnZR9xXpwk7E43SMNGkn+JxJGPFtNvQ48+vV2p+P1ml5PA==}
+
+ css-select@5.2.2:
+ resolution: {integrity: sha512-TizTzUddG/xYLA3NXodFM0fSbNizXjOKhqiQQwvhlspadZokn1KDy0NZFS0wuEubIYAV5/c1/lAr0TaaFXEXzw==}
+
+ css-tree@2.2.1:
+ resolution: {integrity: sha512-OA0mILzGc1kCOCSJerOeqDxDQ4HOh+G8NbOJFOTgOCzpw7fCBubk0fEyxp8AgOL/jvLgYA/uV0cMbe43ElF1JA==}
+ engines: {node: ^10 || ^12.20.0 || ^14.13.0 || >=15.0.0, npm: '>=7.0.0'}
+
+ css-tree@2.3.1:
+ resolution: {integrity: sha512-6Fv1DV/TYw//QF5IzQdqsNDjx/wc8TrMBZsqjL9eW01tWb7R7k/mq+/VXfJCl7SoD5emsJop9cOByJZfs8hYIw==}
+ engines: {node: ^10 || ^12.20.0 || ^14.13.0 || >=15.0.0}
+
+ css-tree@3.2.1:
+ resolution: {integrity: sha512-X7sjQzceUhu1u7Y/ylrRZFU2FS6LRiFVp6rKLPg23y3x3c3DOKAwuXGDp+PAGjh6CSnCjYeAul8pcT8bAl+lSA==}
+ engines: {node: ^10 || ^12.20.0 || ^14.13.0 || >=15.0.0}
+
+ css-what@6.2.2:
+ resolution: {integrity: sha512-u/O3vwbptzhMs3L1fQE82ZSLHQQfto5gyZzwteVIEyeaY5Fc7R4dapF/BvRoSYFeqfBk4m0V1Vafq5Pjv25wvA==}
+ engines: {node: '>= 6'}
+
+ css.escape@1.5.1:
+ resolution: {integrity: sha512-YUifsXXuknHlUsmlgyY0PKzgPOr7/FjCePfHNt0jxm83wHZi44VDMQ7/fGNkjY3/jV1MC+1CmZbaHzugyeRtpg==}
+
+ csso@5.0.5:
+ resolution: {integrity: sha512-0LrrStPOdJj+SPCCrGhzryycLjwcgUSHBtxNA8aIDxf0GLsRh1cKYhB00Gd1lDOS4yGH69+SNn13+TWbVHETFQ==}
+ engines: {node: ^10 || ^12.20.0 || ^14.13.0 || >=15.0.0, npm: '>=7.0.0'}
+
+ data-urls@7.0.0:
+ resolution: {integrity: sha512-23XHcCF+coGYevirZceTVD7NdJOqVn+49IHyxgszm+JIiHLoB2TkmPtsYkNWT1pvRSGkc35L6NHs0yHkN2SumA==}
+ engines: {node: ^20.19.0 || ^22.12.0 || >=24.0.0}
+
+ debug@4.4.3:
+ resolution: {integrity: sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==}
+ engines: {node: '>=6.0'}
+ peerDependencies:
+ supports-color: '*'
+ peerDependenciesMeta:
+ supports-color:
+ optional: true
+
+ decimal.js@10.6.0:
+ resolution: {integrity: sha512-YpgQiITW3JXGntzdUmyUR1V812Hn8T1YVXhCu+wO3OpS4eU9l4YdD3qjyiKdV6mvV29zapkMeD390UVEf2lkUg==}
+
+ decode-named-character-reference@1.3.0:
+ resolution: {integrity: sha512-GtpQYB283KrPp6nRw50q3U9/VfOutZOe103qlN7BPP6Ad27xYnOIWv4lPzo8HCAL+mMZofJ9KEy30fq6MfaK6Q==}
+
+ defu@6.1.4:
+ resolution: {integrity: sha512-mEQCMmwJu317oSz8CwdIOdwf3xMif1ttiM8LTufzc3g6kR+9Pe236twL8j3IYT1F7GfRgGcW6MWxzZjLIkuHIg==}
+
+ delayed-stream@1.0.0:
+ resolution: {integrity: sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==}
+ engines: {node: '>=0.4.0'}
+
+ dequal@2.0.3:
+ resolution: {integrity: sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==}
+ engines: {node: '>=6'}
+
+ destr@2.0.5:
+ resolution: {integrity: sha512-ugFTXCtDZunbzasqBxrK93Ik/DRYsO6S/fedkWEMKqt04xZ4csmnmwGDBAb07QWNaGMAmnTIemsYZCksjATwsA==}
+
+ detect-libc@2.1.2:
+ resolution: {integrity: sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==}
+ engines: {node: '>=8'}
+
+ devalue@5.6.4:
+ resolution: {integrity: sha512-Gp6rDldRsFh/7XuouDbxMH3Mx8GMCcgzIb1pDTvNyn8pZGQ22u+Wa+lGV9dQCltFQ7uVw0MhRyb8XDskNFOReA==}
+
+ devlop@1.1.0:
+ resolution: {integrity: sha512-RWmIqhcFf1lRYBvNmr7qTNuyCt/7/ns2jbpp1+PalgE/rDQcBT0fioSMUpJ93irlUhC5hrg4cYqe6U+0ImW0rA==}
+
+ diff@8.0.4:
+ resolution: {integrity: sha512-DPi0FmjiSU5EvQV0++GFDOJ9ASQUVFh5kD+OzOnYdi7n3Wpm9hWWGfB/O2blfHcMVTL5WkQXSnRiK9makhrcnw==}
+ engines: {node: '>=0.3.1'}
+
+ dlv@1.1.3:
+ resolution: {integrity: sha512-+HlytyjlPKnIG8XuRG8WvmBP8xs8P71y+SKKS6ZXWoEgLuePxtDoUEiH7WkdePWrQ5JBpE6aoVqfZfJUQkjXwA==}
+
+ dom-accessibility-api@0.6.3:
+ resolution: {integrity: sha512-7ZgogeTnjuHbo+ct10G9Ffp0mif17idi0IyWNVA/wcwcm7NPOD/WEHVP3n7n3MhXqxoIYm8d6MuZohYWIZ4T3w==}
+
+ dom-serializer@2.0.0:
+ resolution: {integrity: sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg==}
+
+ domelementtype@2.3.0:
+ resolution: {integrity: sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==}
+
+ domhandler@5.0.3:
+ resolution: {integrity: sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==}
+ engines: {node: '>= 4'}
+
+ domutils@3.2.2:
+ resolution: {integrity: sha512-6kZKyUajlDuqlHKVX1w7gyslj9MPIXzIFiz/rGu35uC1wMi+kMhQwGhl4lt9unC9Vb9INnY9Z3/ZA3+FhASLaw==}
+
+ dot-prop@5.3.0:
+ resolution: {integrity: sha512-QM8q3zDe58hqUqjraQOmzZ1LIH9SWQJTlEKCH4kJ2oQvLZk7RbQXvtDM2XEq3fwkV9CCvvH4LA0AV+ogFsBM2Q==}
+ engines: {node: '>=8'}
+
+ dset@3.1.4:
+ resolution: {integrity: sha512-2QF/g9/zTaPDc3BjNcVTGoBbXBgYfMTTceLaYcFJ/W9kggFUkhxD/hMEeuLKbugyef9SqAx8cpgwlIP/jinUTA==}
+ engines: {node: '>=4'}
+
+ dunder-proto@1.0.1:
+ resolution: {integrity: sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==}
+ engines: {node: '>= 0.4'}
+
+ electron-to-chromium@1.5.321:
+ resolution: {integrity: sha512-L2C7Q279W2D/J4PLZLk7sebOILDSWos7bMsMNN06rK482umHUrh/3lM8G7IlHFOYip2oAg5nha1rCMxr/rs6ZQ==}
+
+ emmet@2.4.11:
+ resolution: {integrity: sha512-23QPJB3moh/U9sT4rQzGgeyyGIrcM+GH5uVYg2C6wZIxAIJq7Ng3QLT79tl8FUwDXhyq9SusfknOrofAKqvgyQ==}
+
+ emoji-regex@8.0.0:
+ resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==}
+
+ encoding-sniffer@0.2.1:
+ resolution: {integrity: sha512-5gvq20T6vfpekVtqrYQsSCFZ1wEg5+wW0/QaZMWkFr6BqD3NfKs0rLCx4rrVlSWJeZb5NBJgVLswK/w2MWU+Gw==}
+
+ end-of-stream@1.4.5:
+ resolution: {integrity: sha512-ooEGc6HP26xXq/N+GCGOT0JKCLDGrq2bQUZrQ7gyrJiZANJ/8YDTxTpQBXGMn+WbIQXNVpyWymm7KYVICQnyOg==}
+
+ enhanced-resolve@5.20.1:
+ resolution: {integrity: sha512-Qohcme7V1inbAfvjItgw0EaxVX5q2rdVEZHRBrEQdRZTssLDGsL8Lwrznl8oQ/6kuTJONLaDcGjkNP247XEhcA==}
+ engines: {node: '>=10.13.0'}
+
+ entities@2.2.0:
+ resolution: {integrity: sha512-p92if5Nz619I0w+akJrLZH0MX0Pb5DX39XOwQTtXSdQQOaYH03S1uIQp4mhOZtAXrxq4ViO67YTiLBo2638o9A==}
+
+ entities@4.5.0:
+ resolution: {integrity: sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==}
+ engines: {node: '>=0.12'}
+
+ entities@6.0.1:
+ resolution: {integrity: sha512-aN97NXWF6AWBTahfVOIrB/NShkzi5H7F9r1s9mD3cDj4Ko5f2qhhVoYMibXF7GlLveb/D2ioWay8lxI97Ven3g==}
+ engines: {node: '>=0.12'}
+
+ entities@7.0.1:
+ resolution: {integrity: sha512-TWrgLOFUQTH994YUyl1yT4uyavY5nNB5muff+RtWaqNVCAK408b5ZnnbNAUEWLTCpum9w6arT70i1XdQ4UeOPA==}
+ engines: {node: '>=0.12'}
+
+ env-paths@2.2.1:
+ resolution: {integrity: sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A==}
+ engines: {node: '>=6'}
+
+ error-ex@1.3.4:
+ resolution: {integrity: sha512-sqQamAnR14VgCr1A618A3sGrygcpK+HEbenA/HiEAkkUwcZIIB/tgWqHFxWgOyDh4nB4JCRimh79dR5Ywc9MDQ==}
+
+ es-define-property@1.0.1:
+ resolution: {integrity: sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==}
+ engines: {node: '>= 0.4'}
+
+ es-errors@1.3.0:
+ resolution: {integrity: sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==}
+ engines: {node: '>= 0.4'}
+
+ es-module-lexer@2.0.0:
+ resolution: {integrity: sha512-5POEcUuZybH7IdmGsD8wlf0AI55wMecM9rVBTI/qEAy2c1kTOm3DjFYjrBdI2K3BaJjJYfYFeRtM0t9ssnRuxw==}
+
+ es-object-atoms@1.1.1:
+ resolution: {integrity: sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==}
+ engines: {node: '>= 0.4'}
+
+ es-set-tostringtag@2.1.0:
+ resolution: {integrity: sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA==}
+ engines: {node: '>= 0.4'}
+
+ esbuild@0.27.4:
+ resolution: {integrity: sha512-Rq4vbHnYkK5fws5NF7MYTU68FPRE1ajX7heQ/8QXXWqNgqqJ/GkmmyxIzUnf2Sr/bakf8l54716CcMGHYhMrrQ==}
+ engines: {node: '>=18'}
+ hasBin: true
+
+ escalade@3.2.0:
+ resolution: {integrity: sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==}
+ engines: {node: '>=6'}
+
+ escape-string-regexp@5.0.0:
+ resolution: {integrity: sha512-/veY75JbMK4j1yjvuUxuVsiS/hr/4iHs9FTT6cgTexxdE0Ly/glccBAkloH/DofkjRbZU3bnoj38mOmhkZ0lHw==}
+ engines: {node: '>=12'}
+
+ estree-walker@2.0.2:
+ resolution: {integrity: sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==}
+
+ estree-walker@3.0.3:
+ resolution: {integrity: sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==}
+
+ eventemitter3@5.0.4:
+ resolution: {integrity: sha512-mlsTRyGaPBjPedk6Bvw+aqbsXDtoAyAzm5MO7JgU+yVRyMQ5O8bD4Kcci7BS85f93veegeCPkL8R4GLClnjLFw==}
+
+ expect-type@1.3.0:
+ resolution: {integrity: sha512-knvyeauYhqjOYvQ66MznSMs83wmHrCycNEN6Ao+2AeYEfxUIkuiVxdEa1qlGEPK+We3n0THiDciYSsCcgW/DoA==}
+ engines: {node: '>=12.0.0'}
+
+ exsolve@1.0.8:
+ resolution: {integrity: sha512-LmDxfWXwcTArk8fUEnOfSZpHOJ6zOMUJKOtFLFqJLoKJetuQG874Uc7/Kki7zFLzYybmZhp1M7+98pfMqeX8yA==}
+
+ extend@3.0.2:
+ resolution: {integrity: sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==}
+
+ extract-zip@2.0.1:
+ resolution: {integrity: sha512-GDhU9ntwuKyGXdZBUgTIe+vXnWj0fppUEtMDL0+idd5Sta8TGpHssn/eusA9mrPr9qNDym6SxAYZjNvCn/9RBg==}
+ engines: {node: '>= 10.17.0'}
+ hasBin: true
+
+ fast-deep-equal@3.1.3:
+ resolution: {integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==}
+
+ fast-uri@3.1.0:
+ resolution: {integrity: sha512-iPeeDKJSWf4IEOasVVrknXpaBV0IApz/gp7S2bb7Z4Lljbl2MGJRqInZiUrQwV16cpzw/D3S5j5Julj/gT52AA==}
+
+ fd-slicer@1.1.0:
+ resolution: {integrity: sha512-cE1qsB/VwyQozZ+q1dGxR8LBYNZeofhEdUNGSMbQD3Gw2lAzX9Zb3uIU6Ebc/Fmyjo9AWWfnn0AUCHqtevs/8g==}
+
+ fdir@6.5.0:
+ resolution: {integrity: sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==}
+ engines: {node: '>=12.0.0'}
+ peerDependencies:
+ picomatch: ^3 || ^4
+ peerDependenciesMeta:
+ picomatch:
+ optional: true
+
+ fflate@0.8.2:
+ resolution: {integrity: sha512-cPJU47OaAoCbg0pBvzsgpTPhmhqI5eJjh/JIu8tPj5q+T7iLvW/JAYUqmE7KOB4R1ZyEhzBaIQpQpardBF5z8A==}
+
+ flatted@3.4.0:
+ resolution: {integrity: sha512-kC6Bb+ooptOIvWj5B63EQWkF0FEnNjV2ZNkLMLZRDDduIiWeFF4iKnslwhiWxjAdbg4NzTNo6h0qLuvFrcx+Sw==}
+
+ flattie@1.1.1:
+ resolution: {integrity: sha512-9UbaD6XdAL97+k/n+N7JwX46K/M6Zc6KcFYskrYL8wbBV/Uyk0CTAMY0VT+qiK5PM7AIc9aTWYtq65U7T+aCNQ==}
+ engines: {node: '>=8'}
+
+ fontace@0.4.1:
+ resolution: {integrity: sha512-lDMvbAzSnHmbYMTEld5qdtvNH2/pWpICOqpean9IgC7vUbUJc3k+k5Dokp85CegamqQpFbXf0rAVkbzpyTA8aw==}
+
+ fontkitten@1.0.3:
+ resolution: {integrity: sha512-Wp1zXWPVUPBmfoa3Cqc9ctaKuzKAV6uLstRqlR56kSjplf5uAce+qeyYym7F+PHbGTk+tCEdkCW6RD7DX/gBZw==}
+ engines: {node: '>=20'}
+
+ form-data@2.5.5:
+ resolution: {integrity: sha512-jqdObeR2rxZZbPSGL+3VckHMYtu+f9//KXBsVny6JSX/pa38Fy+bGjuG8eW/H6USNQWhLi8Num++cU2yOCNz4A==}
+ engines: {node: '>= 0.12'}
+
+ fraction.js@5.3.4:
+ resolution: {integrity: sha512-1X1NTtiJphryn/uLQz3whtY6jK3fTqoE3ohKs0tT+Ujr1W59oopxmoEh7Lu5p6vBaPbgoM0bzveAW4Qi5RyWDQ==}
+
+ fsevents@2.3.2:
+ resolution: {integrity: sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==}
+ engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0}
+ os: [darwin]
+
+ fsevents@2.3.3:
+ resolution: {integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==}
+ engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0}
+ os: [darwin]
+
+ function-bind@1.1.2:
+ resolution: {integrity: sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==}
+
+ get-caller-file@2.0.5:
+ resolution: {integrity: sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==}
+ engines: {node: 6.* || 8.* || >= 10.*}
+
+ get-intrinsic@1.3.0:
+ resolution: {integrity: sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==}
+ engines: {node: '>= 0.4'}
+
+ get-port@3.2.0:
+ resolution: {integrity: sha512-x5UJKlgeUiNT8nyo/AcnwLnZuZNcSjSw0kogRB+Whd1fjjFq4B1hySFxSFWWSn4mIBzg3sRNUDFYc4g5gjPoLg==}
+ engines: {node: '>=4'}
+
+ get-proto@1.0.1:
+ resolution: {integrity: sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==}
+ engines: {node: '>= 0.4'}
+
+ get-stream@5.2.0:
+ resolution: {integrity: sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==}
+ engines: {node: '>=8'}
+
+ git-raw-commits@5.0.1:
+ resolution: {integrity: sha512-Y+csSm2GD/PCSh6Isd/WiMjNAydu0VBiG9J7EdQsNA5P9uXvLayqjmTsNlK5Gs9IhblFZqOU0yid5Il5JPoLiQ==}
+ engines: {node: '>=18'}
+ hasBin: true
+
+ github-slugger@2.0.0:
+ resolution: {integrity: sha512-IaOQ9puYtjrkq7Y0Ygl9KDZnrf/aiUJYUpVf89y8kyaxbRG7Y1SrX/jaumrv81vc61+kiMempujsM3Yw7w5qcw==}
+
+ global-directory@4.0.1:
+ resolution: {integrity: sha512-wHTUcDUoZ1H5/0iVqEudYW4/kAlN5cZ3j/bXn0Dpbizl9iaUVeWSHqiOjsgk6OW2bkLclbBjzewBz6weQ1zA2Q==}
+ engines: {node: '>=18'}
+
+ globals@15.15.0:
+ resolution: {integrity: sha512-7ACyT3wmyp3I61S4fG682L0VA2RGD9otkqGJIwNUMF1SWUombIIk+af1unuDYgMm082aHYwD+mzJvv9Iu8dsgg==}
+ engines: {node: '>=18'}
+
+ gopd@1.2.0:
+ resolution: {integrity: sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==}
+ engines: {node: '>= 0.4'}
+
+ graceful-fs@4.2.11:
+ resolution: {integrity: sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==}
+
+ h3@1.15.10:
+ resolution: {integrity: sha512-YzJeWSkDZxAhvmp8dexjRK5hxziRO7I9m0N53WhvYL5NiWfkUkzssVzY9jvGu0HBoLFW6+duYmNSn6MaZBCCtg==}
+
+ has-flag@4.0.0:
+ resolution: {integrity: sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==}
+ engines: {node: '>=8'}
+
+ has-symbols@1.1.0:
+ resolution: {integrity: sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==}
+ engines: {node: '>= 0.4'}
+
+ has-tostringtag@1.0.2:
+ resolution: {integrity: sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==}
+ engines: {node: '>= 0.4'}
+
+ hasown@2.0.2:
+ resolution: {integrity: sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==}
+ engines: {node: '>= 0.4'}
+
+ hast-util-from-html@2.0.3:
+ resolution: {integrity: sha512-CUSRHXyKjzHov8yKsQjGOElXy/3EKpyX56ELnkHH34vDVw1N1XSQ1ZcAvTyAPtGqLTuKP/uxM+aLkSPqF/EtMw==}
+
+ hast-util-from-parse5@8.0.3:
+ resolution: {integrity: sha512-3kxEVkEKt0zvcZ3hCRYI8rqrgwtlIOFMWkbclACvjlDw8Li9S2hk/d51OI0nr/gIpdMHNepwgOKqZ/sy0Clpyg==}
+
+ hast-util-is-element@3.0.0:
+ resolution: {integrity: sha512-Val9mnv2IWpLbNPqc/pUem+a7Ipj2aHacCwgNfTiK0vJKl0LF+4Ba4+v1oPHFpf3bLYmreq0/l3Gud9S5OH42g==}
+
+ hast-util-parse-selector@4.0.0:
+ resolution: {integrity: sha512-wkQCkSYoOGCRKERFWcxMVMOcYE2K1AaNLU8DXS9arxnLOUEWbOXKXiJUNzEpqZ3JOKpnha3jkFrumEjVliDe7A==}
+
+ hast-util-raw@9.1.0:
+ resolution: {integrity: sha512-Y8/SBAHkZGoNkpzqqfCldijcuUKh7/su31kEBp67cFY09Wy0mTRgtsLYsiIxMJxlu0f6AA5SUTbDR8K0rxnbUw==}
+
+ hast-util-to-html@9.0.5:
+ resolution: {integrity: sha512-OguPdidb+fbHQSU4Q4ZiLKnzWo8Wwsf5bZfbvu7//a9oTYoqD/fWpe96NuHkoS9h0ccGOTe0C4NGXdtS0iObOw==}
+
+ hast-util-to-parse5@8.0.1:
+ resolution: {integrity: sha512-MlWT6Pjt4CG9lFCjiz4BH7l9wmrMkfkJYCxFwKQic8+RTZgWPuWxwAfjJElsXkex7DJjfSJsQIt931ilUgmwdA==}
+
+ hast-util-to-text@4.0.2:
+ resolution: {integrity: sha512-KK6y/BN8lbaq654j7JgBydev7wuNMcID54lkRav1P0CaE1e47P72AWWPiGKXTJU271ooYzcvTAn/Zt0REnvc7A==}
+
+ hast-util-whitespace@3.0.0:
+ resolution: {integrity: sha512-88JUN06ipLwsnv+dVn+OIYOvAuvBMy/Qoi6O7mQHxdPXpjy+Cd6xRkWwux7DKO+4sYILtLBRIKgsdpS2gQc7qw==}
+
+ hastscript@9.0.1:
+ resolution: {integrity: sha512-g7df9rMFX/SPi34tyGCyUBREQoKkapwdY/T04Qn9TDWfHhAYt4/I0gMVirzK5wEzeUqIjEB+LXC/ypb7Aqno5w==}
+
+ html-encoding-sniffer@6.0.0:
+ resolution: {integrity: sha512-CV9TW3Y3f8/wT0BRFc1/KAVQ3TUHiXmaAb6VW9vtiMFf7SLoMd1PdAc4W3KFOFETBJUb90KatHqlsZMWV+R9Gg==}
+ engines: {node: ^20.19.0 || ^22.12.0 || >=24.0.0}
+
+ html-escaper@2.0.2:
+ resolution: {integrity: sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==}
+
+ html-escaper@3.0.3:
+ resolution: {integrity: sha512-RuMffC89BOWQoY0WKGpIhn5gX3iI54O6nRA0yC124NYVtzjmFWBIiFd8M0x+ZdX0P9R4lADg1mgP8C7PxGOWuQ==}
+
+ html-void-elements@3.0.0:
+ resolution: {integrity: sha512-bEqo66MRXsUGxWHV5IP0PUiAWwoEjba4VCzg0LjFJBpchPaTfyfCKTG6bc5F8ucKec3q5y6qOdGyYTSBEvhCrg==}
+
+ htmlparser2@10.1.0:
+ resolution: {integrity: sha512-VTZkM9GWRAtEpveh7MSF6SjjrpNVNNVJfFup7xTY3UpFtm67foy9HDVXneLtFVt4pMz5kZtgNcvCniNFb1hlEQ==}
+
+ http-basic@8.1.3:
+ resolution: {integrity: sha512-/EcDMwJZh3mABI2NhGfHOGOeOZITqfkEO4p/xK+l3NpyncIHUQBoMvCSF/b5GqvKtySC2srL/GGG3+EtlqlmCw==}
+ engines: {node: '>=6.0.0'}
+
+ http-cache-semantics@4.2.0:
+ resolution: {integrity: sha512-dTxcvPXqPvXBQpq5dUr6mEMJX4oIEFv6bwom3FDwKRDsuIjjJGANqhBuoAn9c1RQJIdAKav33ED65E2ys+87QQ==}
+
+ http-response-object@3.0.2:
+ resolution: {integrity: sha512-bqX0XTF6fnXSQcEJ2Iuyr75yVakyjIDCqroJQ/aHfSdlM743Cwqoi2nDYMzLGWUcuTWGWy8AAvOKXTfiv6q9RA==}
+
+ iconv-lite@0.6.3:
+ resolution: {integrity: sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==}
+ engines: {node: '>=0.10.0'}
+
+ import-fresh@3.3.1:
+ resolution: {integrity: sha512-TR3KfrTZTYLPB6jUjfx6MF9WcWrHL9su5TObK4ZkYgBdWKPOFoSoQIdEuTuR82pmtxH2spWG9h6etwfr1pLBqQ==}
+ engines: {node: '>=6'}
+
+ import-meta-resolve@4.2.0:
+ resolution: {integrity: sha512-Iqv2fzaTQN28s/FwZAoFq0ZSs/7hMAHJVX+w8PZl3cY19Pxk6jFFalxQoIfW2826i/fDLXv8IiEZRIT0lDuWcg==}
+
+ indent-string@4.0.0:
+ resolution: {integrity: sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==}
+ engines: {node: '>=8'}
+
+ inherits@2.0.4:
+ resolution: {integrity: sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==}
+
+ ini@4.1.1:
+ resolution: {integrity: sha512-QQnnxNyfvmHFIsj7gkPcYymR8Jdw/o7mp5ZFihxn6h8Ci6fh3Dx4E1gPjpQEpIuPo9XVNY/ZUwh4BPMjGyL01g==}
+ engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0}
+
+ iron-webcrypto@1.2.1:
+ resolution: {integrity: sha512-feOM6FaSr6rEABp/eDfVseKyTMDt+KGpeB35SkVn9Tyn0CqvVsY3EwI0v5i8nMHyJnzCIQf7nsy3p41TPkJZhg==}
+
+ is-arrayish@0.2.1:
+ resolution: {integrity: sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==}
+
+ is-docker@3.0.0:
+ resolution: {integrity: sha512-eljcgEDlEns/7AXFosB5K/2nCM4P7FQPkGc/DWLy5rmFEWvZayGrik1d9/QIY5nJ4f9YsVvBkA6kJpHn9rISdQ==}
+ engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0}
+ hasBin: true
+
+ is-fullwidth-code-point@3.0.0:
+ resolution: {integrity: sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==}
+ engines: {node: '>=8'}
+
+ is-inside-container@1.0.0:
+ resolution: {integrity: sha512-KIYLCCJghfHZxqjYBE7rEy0OBuTd5xCHS7tHVgvCLkx7StIoaxwNW3hCALgEUjFfeRk+MG/Qxmp/vtETEF3tRA==}
+ engines: {node: '>=14.16'}
+ hasBin: true
+
+ is-obj@2.0.0:
+ resolution: {integrity: sha512-drqDG3cbczxxEJRoOXcOjtdp1J/lyp1mNn0xaznRs8+muBhgQcrnbspox5X5fOw0HnMnbfDzvnEMEtqDEJEo8w==}
+ engines: {node: '>=8'}
+
+ is-plain-obj@4.1.0:
+ resolution: {integrity: sha512-+Pgi+vMuUNkJyExiMBt5IlFoMyKnr5zhJ4Uspz58WOhBF5QoIZkFyNHIbBAtHwzVAgk5RtndVNsDRN61/mmDqg==}
+ engines: {node: '>=12'}
+
+ is-potential-custom-element-name@1.0.1:
+ resolution: {integrity: sha512-bCYeRA2rVibKZd+s2625gGnGF/t7DSqDs4dP7CrLA1m7jKWz6pps0LpYLJN8Q64HtmPKJ1hrN3nzPNKFEKOUiQ==}
+
+ is-wsl@3.1.1:
+ resolution: {integrity: sha512-e6rvdUCiQCAuumZslxRJWR/Doq4VpPR82kqclvcS0efgt430SlGIk05vdCN58+VrzgtIcfNODjozVielycD4Sw==}
+ engines: {node: '>=16'}
+
+ isarray@1.0.0:
+ resolution: {integrity: sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==}
+
+ istanbul-lib-coverage@3.2.2:
+ resolution: {integrity: sha512-O8dpsF+r0WV/8MNRKfnmrtCWhuKjxrq2w+jpzBL5UZKTi2LeVWnWOmWRxFlesJONmc+wLAGvKQZEOanko0LFTg==}
+ engines: {node: '>=8'}
+
+ istanbul-lib-report@3.0.1:
+ resolution: {integrity: sha512-GCfE1mtsHGOELCU8e/Z7YWzpmybrx/+dSTfLrvY8qRmaY6zXTKWn6WQIjaAFw069icm6GVMNkgu0NzI4iPZUNw==}
+ engines: {node: '>=10'}
+
+ istanbul-reports@3.2.0:
+ resolution: {integrity: sha512-HGYWWS/ehqTV3xN10i23tkPkpH46MLCIMFNCaaKNavAXTF1RkqxawEPtnjnGZ6XKSInBKkiOA5BKS+aZiY3AvA==}
+ engines: {node: '>=8'}
+
+ jiti@2.6.1:
+ resolution: {integrity: sha512-ekilCSN1jwRvIbgeg/57YFh8qQDNbwDb9xT/qu2DAHbFFZUicIl4ygVaAvzveMhMVr3LnpSKTNnwt8PoOfmKhQ==}
+ hasBin: true
+
+ js-tokens@10.0.0:
+ resolution: {integrity: sha512-lM/UBzQmfJRo9ABXbPWemivdCW8V2G8FHaHdypQaIy523snUjog0W71ayWXTjiR+ixeMyVHN2XcpnTd/liPg/Q==}
+
+ js-tokens@4.0.0:
+ resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==}
+
+ js-yaml@4.1.1:
+ resolution: {integrity: sha512-qQKT4zQxXl8lLwBtHMWwaTcGfFOZviOJet3Oy/xmGk2gZH677CJM9EvtfdSkgWcATZhj/55JZ0rmy3myCT5lsA==}
+ hasBin: true
+
+ jsdom@29.0.1:
+ resolution: {integrity: sha512-z6JOK5gRO7aMybVq/y/MlIpKh8JIi68FBKMUtKkK2KH/wMSRlCxQ682d08LB9fYXplyY/UXG8P4XXTScmdjApg==}
+ engines: {node: ^20.19.0 || ^22.13.0 || >=24.0.0}
+ peerDependencies:
+ canvas: ^3.0.0
+ peerDependenciesMeta:
+ canvas:
+ optional: true
+
+ json-parse-even-better-errors@2.3.1:
+ resolution: {integrity: sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==}
+
+ json-schema-traverse@1.0.0:
+ resolution: {integrity: sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==}
+
+ jsonc-parser@2.3.1:
+ resolution: {integrity: sha512-H8jvkz1O50L3dMZCsLqiuB2tA7muqbSg1AtGEkN0leAqGjsUzDJir3Zwr02BhqdcITPg3ei3mZ+HjMocAknhhg==}
+
+ jsonc-parser@3.3.1:
+ resolution: {integrity: sha512-HUgH65KyejrUFPvHFPbqOY0rsFip3Bo5wb4ngvdi1EpCYWUQDC5V+Y7mZws+DLkr4M//zQJoanu1SP+87Dv1oQ==}
+
+ jsonschema@1.5.0:
+ resolution: {integrity: sha512-K+A9hhqbn0f3pJX17Q/7H6yQfD/5OXgdrR5UE12gMXCiN9D5Xq2o5mddV2QEcX/bjla99ASsAAQUyMCCRWAEhw==}
+
+ kleur@4.1.5:
+ resolution: {integrity: sha512-o+NO+8WrRiQEE4/7nwRJhN1HWpVmJm511pBHUxPLtp0BUISzlBplORYSmTclCnJvQq2tKu/sgl3xVpkc7ZWuQQ==}
+ engines: {node: '>=6'}
+
+ kolorist@1.8.0:
+ resolution: {integrity: sha512-Y+60/zizpJ3HRH8DCss+q95yr6145JXZo46OTpFvDZWLfRCE4qChOyk1b26nMaNpfHHgxagk9dXT5OP0Tfe+dQ==}
+
+ lefthook-darwin-arm64@2.1.4:
+ resolution: {integrity: sha512-BUAAE9+rUrjr39a+wH/1zHmGrDdwUQ2Yq/z6BQbM/yUb9qtXBRcQ5eOXxApqWW177VhGBpX31aqIlfAZ5Q7wzw==}
+ cpu: [arm64]
+ os: [darwin]
+
+ lefthook-darwin-x64@2.1.4:
+ resolution: {integrity: sha512-K1ncIMEe84fe+ss1hQNO7rIvqiKy2TJvTFpkypvqFodT7mJXZn7GLKYTIXdIuyPAYthRa9DwFnx5uMoHwD2F1Q==}
+ cpu: [x64]
+ os: [darwin]
+
+ lefthook-freebsd-arm64@2.1.4:
+ resolution: {integrity: sha512-PVUhjOhVN71YaYsVdQyNbFZ4a2jFB2Tg5hKrrn9kaWpx64aLz/XivLjwr8sEuTaP1GRlEWBpW6Bhrcsyo39qFw==}
+ cpu: [arm64]
+ os: [freebsd]
+
+ lefthook-freebsd-x64@2.1.4:
+ resolution: {integrity: sha512-ZWV9o/LeyWNEBoVO+BhLqxH3rGTba05nkm5NvMjEFSj7LbUNUDbQmupZwtHl1OMGJO66eZP0CalzRfUH6GhBxQ==}
+ cpu: [x64]
+ os: [freebsd]
+
+ lefthook-linux-arm64@2.1.4:
+ resolution: {integrity: sha512-iWN0pGnTjrIvNIcSI1vQBJXUbybTqJ5CLMniPA0olabMXQfPDrdMKVQe+mgdwHK+E3/Y0H0ZNL3lnOj6Sk6szA==}
+ cpu: [arm64]
+ os: [linux]
+
+ lefthook-linux-x64@2.1.4:
+ resolution: {integrity: sha512-96bTBE/JdYgqWYAJDh+/e/0MaxJ25XTOAk7iy/fKoZ1ugf6S0W9bEFbnCFNooXOcxNVTan5xWKfcjJmPIKtsJA==}
+ cpu: [x64]
+ os: [linux]
+
+ lefthook-openbsd-arm64@2.1.4:
+ resolution: {integrity: sha512-oYUoK6AIJNEr9lUSpIMj6g7sWzotvtc3ryw7yoOyQM6uqmEduw73URV/qGoUcm4nqqmR93ZalZwR2r3Gd61zvw==}
+ cpu: [arm64]
+ os: [openbsd]
+
+ lefthook-openbsd-x64@2.1.4:
+ resolution: {integrity: sha512-i/Dv9Jcm68y9cggr1PhyUhOabBGP9+hzQPoiyOhKks7y9qrJl79A8XfG6LHekSuYc2VpiSu5wdnnrE1cj2nfTg==}
+ cpu: [x64]
+ os: [openbsd]
+
+ lefthook-windows-arm64@2.1.4:
+ resolution: {integrity: sha512-hSww7z+QX4YMnw2lK7DMrs3+w7NtxksuMKOkCKGyxUAC/0m1LAICo0ZbtdDtZ7agxRQQQ/SEbzFRhU5ysNcbjA==}
+ cpu: [arm64]
+ os: [win32]
+
+ lefthook-windows-x64@2.1.4:
+ resolution: {integrity: sha512-eE68LwnogxwcPgGsbVGPGxmghyMGmU9SdGwcc+uhGnUxPz1jL89oECMWJNc36zjVK24umNeDAzB5KA3lw1MuWw==}
+ cpu: [x64]
+ os: [win32]
+
+ lefthook@2.1.4:
+ resolution: {integrity: sha512-JNfJ5gAn0KADvJ1I6/xMcx70+/6TL6U9gqGkKvPw5RNMfatC7jIg0Evl97HN846xmfz959BV70l8r3QsBJk30w==}
+ hasBin: true
+
+ lightningcss-android-arm64@1.32.0:
+ resolution: {integrity: sha512-YK7/ClTt4kAK0vo6w3X+Pnm0D2cf2vPHbhOXdoNti1Ga0al1P4TBZhwjATvjNwLEBCnKvjJc2jQgHXH0NEwlAg==}
+ engines: {node: '>= 12.0.0'}
+ cpu: [arm64]
+ os: [android]
+
+ lightningcss-darwin-arm64@1.32.0:
+ resolution: {integrity: sha512-RzeG9Ju5bag2Bv1/lwlVJvBE3q6TtXskdZLLCyfg5pt+HLz9BqlICO7LZM7VHNTTn/5PRhHFBSjk5lc4cmscPQ==}
+ engines: {node: '>= 12.0.0'}
+ cpu: [arm64]
+ os: [darwin]
+
+ lightningcss-darwin-x64@1.32.0:
+ resolution: {integrity: sha512-U+QsBp2m/s2wqpUYT/6wnlagdZbtZdndSmut/NJqlCcMLTWp5muCrID+K5UJ6jqD2BFshejCYXniPDbNh73V8w==}
+ engines: {node: '>= 12.0.0'}
+ cpu: [x64]
+ os: [darwin]
+
+ lightningcss-freebsd-x64@1.32.0:
+ resolution: {integrity: sha512-JCTigedEksZk3tHTTthnMdVfGf61Fky8Ji2E4YjUTEQX14xiy/lTzXnu1vwiZe3bYe0q+SpsSH/CTeDXK6WHig==}
+ engines: {node: '>= 12.0.0'}
+ cpu: [x64]
+ os: [freebsd]
+
+ lightningcss-linux-arm-gnueabihf@1.32.0:
+ resolution: {integrity: sha512-x6rnnpRa2GL0zQOkt6rts3YDPzduLpWvwAF6EMhXFVZXD4tPrBkEFqzGowzCsIWsPjqSK+tyNEODUBXeeVHSkw==}
+ engines: {node: '>= 12.0.0'}
+ cpu: [arm]
+ os: [linux]
+
+ lightningcss-linux-arm64-gnu@1.32.0:
+ resolution: {integrity: sha512-0nnMyoyOLRJXfbMOilaSRcLH3Jw5z9HDNGfT/gwCPgaDjnx0i8w7vBzFLFR1f6CMLKF8gVbebmkUN3fa/kQJpQ==}
+ engines: {node: '>= 12.0.0'}
+ cpu: [arm64]
+ os: [linux]
+
+ lightningcss-linux-arm64-musl@1.32.0:
+ resolution: {integrity: sha512-UpQkoenr4UJEzgVIYpI80lDFvRmPVg6oqboNHfoH4CQIfNA+HOrZ7Mo7KZP02dC6LjghPQJeBsvXhJod/wnIBg==}
+ engines: {node: '>= 12.0.0'}
+ cpu: [arm64]
+ os: [linux]
+
+ lightningcss-linux-x64-gnu@1.32.0:
+ resolution: {integrity: sha512-V7Qr52IhZmdKPVr+Vtw8o+WLsQJYCTd8loIfpDaMRWGUZfBOYEJeyJIkqGIDMZPwPx24pUMfwSxxI8phr/MbOA==}
+ engines: {node: '>= 12.0.0'}
+ cpu: [x64]
+ os: [linux]
+
+ lightningcss-linux-x64-musl@1.32.0:
+ resolution: {integrity: sha512-bYcLp+Vb0awsiXg/80uCRezCYHNg1/l3mt0gzHnWV9XP1W5sKa5/TCdGWaR/zBM2PeF/HbsQv/j2URNOiVuxWg==}
+ engines: {node: '>= 12.0.0'}
+ cpu: [x64]
+ os: [linux]
+
+ lightningcss-win32-arm64-msvc@1.32.0:
+ resolution: {integrity: sha512-8SbC8BR40pS6baCM8sbtYDSwEVQd4JlFTOlaD3gWGHfThTcABnNDBda6eTZeqbofalIJhFx0qKzgHJmcPTnGdw==}
+ engines: {node: '>= 12.0.0'}
+ cpu: [arm64]
+ os: [win32]
+
+ lightningcss-win32-x64-msvc@1.32.0:
+ resolution: {integrity: sha512-Amq9B/SoZYdDi1kFrojnoqPLxYhQ4Wo5XiL8EVJrVsB8ARoC1PWW6VGtT0WKCemjy8aC+louJnjS7U18x3b06Q==}
+ engines: {node: '>= 12.0.0'}
+ cpu: [x64]
+ os: [win32]
+
+ lightningcss@1.32.0:
+ resolution: {integrity: sha512-NXYBzinNrblfraPGyrbPoD19C1h9lfI/1mzgWYvXUTe414Gz/X1FD2XBZSZM7rRTrMA8JL3OtAaGifrIKhQ5yQ==}
+ engines: {node: '>= 12.0.0'}
+
+ lines-and-columns@1.2.4:
+ resolution: {integrity: sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==}
+
+ local-pkg@1.1.2:
+ resolution: {integrity: sha512-arhlxbFRmoQHl33a0Zkle/YWlmNwoyt6QNZEIJcqNbdrsix5Lvc4HyyI3EnwxTYlZYc32EbYrQ8SzEZ7dqgg9A==}
+ engines: {node: '>=14'}
+
+ lodash.camelcase@4.3.0:
+ resolution: {integrity: sha512-TwuEnCnxbc3rAvhf/LbG7tJUDzhqXyFnv3dtzLOPgCG/hODL7WFnsbwktkD7yUV0RrreP/l1PALq/YSg6VvjlA==}
+
+ lodash.kebabcase@4.1.1:
+ resolution: {integrity: sha512-N8XRTIMMqqDgSy4VLKPnJ/+hpGZN+PHQiJnSenYqPaVV/NCqEogTnAdZLQiGKhxX+JCs8waWq2t1XHWKOmlY8g==}
+
+ lodash.mergewith@4.6.2:
+ resolution: {integrity: sha512-GK3g5RPZWTRSeLSpgP8Xhra+pnjBC56q9FZYe1d5RN3TJ35dbkGy3YqBSMbyCrlbi+CM9Z3Jk5yTL7RCsqboyQ==}
+
+ lodash.snakecase@4.1.1:
+ resolution: {integrity: sha512-QZ1d4xoBHYUeuouhEq3lk3Uq7ldgyFXGBhg04+oRLnIz8o9T65Eh+8YdroUwn846zchkA9yDsDl5CVVaV2nqYw==}
+
+ lodash.startcase@4.4.0:
+ resolution: {integrity: sha512-+WKqsK294HMSc2jEbNgpHpd0JfIBhp7rEV4aqXWqFr6AlXov+SlcgB1Fv01y2kGe3Gc8nMW7VA0SrGuSkRfIEg==}
+
+ lodash.upperfirst@4.3.1:
+ resolution: {integrity: sha512-sReKOYJIJf74dhJONhU4e0/shzi1trVbSWDOhKYE5XV2O+H7Sb2Dihwuc7xWxVl+DgFPyTqIN3zMfT9cq5iWDg==}
+
+ longest-streak@3.1.0:
+ resolution: {integrity: sha512-9Ri+o0JYgehTaVBBDoMqIl8GXtbWg711O3srftcHhZ0dqnETqLaoIK0x17fUw9rFSlK/0NlsKe0Ahhyl5pXE2g==}
+
+ lru-cache@11.2.7:
+ resolution: {integrity: sha512-aY/R+aEsRelme17KGQa/1ZSIpLpNYYrhcrepKTZgE+W3WM16YMCaPwOHLHsmopZHELU0Ojin1lPVxKR0MihncA==}
+ engines: {node: 20 || >=22}
+
+ magic-string@0.30.21:
+ resolution: {integrity: sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ==}
+
+ magicast@0.5.2:
+ resolution: {integrity: sha512-E3ZJh4J3S9KfwdjZhe2afj6R9lGIN5Pher1pF39UGrXRqq/VDaGVIGN13BjHd2u8B61hArAGOnso7nBOouW3TQ==}
+
+ make-dir@4.0.0:
+ resolution: {integrity: sha512-hXdUTZYIVOt1Ex//jAQi+wTZZpUpwBj/0QsOzqegb3rGMMeJiSEu5xLHnYfBrRV4RH2+OCSOO95Is/7x1WJ4bw==}
+ engines: {node: '>=10'}
+
+ markdown-table@3.0.4:
+ resolution: {integrity: sha512-wiYz4+JrLyb/DqW2hkFJxP7Vd7JuTDm77fvbM8VfEQdmSMqcImWeeRbHwZjBjIFki/VaMK2BhFi7oUUZeM5bqw==}
+
+ math-intrinsics@1.1.0:
+ resolution: {integrity: sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==}
+ engines: {node: '>= 0.4'}
+
+ mdast-util-definitions@6.0.0:
+ resolution: {integrity: sha512-scTllyX6pnYNZH/AIp/0ePz6s4cZtARxImwoPJ7kS42n+MnVsI4XbnG6d4ibehRIldYMWM2LD7ImQblVhUejVQ==}
+
+ mdast-util-find-and-replace@3.0.2:
+ resolution: {integrity: sha512-Tmd1Vg/m3Xz43afeNxDIhWRtFZgM2VLyaf4vSTYwudTyeuTneoL3qtWMA5jeLyz/O1vDJmmV4QuScFCA2tBPwg==}
+
+ mdast-util-from-markdown@2.0.3:
+ resolution: {integrity: sha512-W4mAWTvSlKvf8L6J+VN9yLSqQ9AOAAvHuoDAmPkz4dHf553m5gVj2ejadHJhoJmcmxEnOv6Pa8XJhpxE93kb8Q==}
+
+ mdast-util-gfm-autolink-literal@2.0.1:
+ resolution: {integrity: sha512-5HVP2MKaP6L+G6YaxPNjuL0BPrq9orG3TsrZ9YXbA3vDw/ACI4MEsnoDpn6ZNm7GnZgtAcONJyPhOP8tNJQavQ==}
+
+ mdast-util-gfm-footnote@2.1.0:
+ resolution: {integrity: sha512-sqpDWlsHn7Ac9GNZQMeUzPQSMzR6Wv0WKRNvQRg0KqHh02fpTz69Qc1QSseNX29bhz1ROIyNyxExfawVKTm1GQ==}
+
+ mdast-util-gfm-strikethrough@2.0.0:
+ resolution: {integrity: sha512-mKKb915TF+OC5ptj5bJ7WFRPdYtuHv0yTRxK2tJvi+BDqbkiG7h7u/9SI89nRAYcmap2xHQL9D+QG/6wSrTtXg==}
+
+ mdast-util-gfm-table@2.0.0:
+ resolution: {integrity: sha512-78UEvebzz/rJIxLvE7ZtDd/vIQ0RHv+3Mh5DR96p7cS7HsBhYIICDBCu8csTNWNO6tBWfqXPWekRuj2FNOGOZg==}
+
+ mdast-util-gfm-task-list-item@2.0.0:
+ resolution: {integrity: sha512-IrtvNvjxC1o06taBAVJznEnkiHxLFTzgonUdy8hzFVeDun0uTjxxrRGVaNFqkU1wJR3RBPEfsxmU6jDWPofrTQ==}
+
+ mdast-util-gfm@3.1.0:
+ resolution: {integrity: sha512-0ulfdQOM3ysHhCJ1p06l0b0VKlhU0wuQs3thxZQagjcjPrlFRqY215uZGHHJan9GEAXd9MbfPjFJz+qMkVR6zQ==}
+
+ mdast-util-phrasing@4.1.0:
+ resolution: {integrity: sha512-TqICwyvJJpBwvGAMZjj4J2n0X8QWp21b9l0o7eXyVJ25YNWYbJDVIyD1bZXE6WtV6RmKJVYmQAKWa0zWOABz2w==}
+
+ mdast-util-to-hast@13.2.1:
+ resolution: {integrity: sha512-cctsq2wp5vTsLIcaymblUriiTcZd0CwWtCbLvrOzYCDZoWyMNV8sZ7krj09FSnsiJi3WVsHLM4k6Dq/yaPyCXA==}
+
+ mdast-util-to-markdown@2.1.2:
+ resolution: {integrity: sha512-xj68wMTvGXVOKonmog6LwyJKrYXZPvlwabaryTjLh9LuvovB/KAH+kvi8Gjj+7rJjsFi23nkUxRQv1KqSroMqA==}
+
+ mdast-util-to-string@4.0.0:
+ resolution: {integrity: sha512-0H44vDimn51F0YwvxSJSm0eCDOJTRlmN0R1yBh4HLj9wiV1Dn0QoXGbvFAWj2hSItVTlCmBF1hqKlIyUBVFLPg==}
+
+ mdn-data@2.0.28:
+ resolution: {integrity: sha512-aylIc7Z9y4yzHYAJNuESG3hfhC+0Ibp/MAMiaOZgNv4pmEdFyfZhhhny4MNiAfWdBQ1RQ2mfDWmM1x8SvGyp8g==}
+
+ mdn-data@2.0.30:
+ resolution: {integrity: sha512-GaqWWShW4kv/G9IEucWScBx9G1/vsFZZJUO+tD26M8J8z3Kw5RDQjaoZe03YAClgeS/SWPOcb4nkFBTEi5DUEA==}
+
+ mdn-data@2.27.1:
+ resolution: {integrity: sha512-9Yubnt3e8A0OKwxYSXyhLymGW4sCufcLG6VdiDdUGVkPhpqLxlvP5vl1983gQjJl3tqbrM731mjaZaP68AgosQ==}
+
+ meow@13.2.0:
+ resolution: {integrity: sha512-pxQJQzB6djGPXh08dacEloMFopsOqGVRKFPYvPOt9XDZ1HasbgDZA74CJGreSU4G3Ak7EFJGoiH2auq+yXISgA==}
+ engines: {node: '>=18'}
+
+ metagroup-schema-tools@1.1.0:
+ resolution: {integrity: sha512-TyHiFMBOfJrF26N4v4lffk/4rJA8z7RnEvR/Sy8SOCH3PxuAGYfT/QYvMZgHy8VtCdxdaoVbxjfY22H+YQxXYQ==}
+
+ micromark-core-commonmark@2.0.3:
+ resolution: {integrity: sha512-RDBrHEMSxVFLg6xvnXmb1Ayr2WzLAWjeSATAoxwKYJV94TeNavgoIdA0a9ytzDSVzBy2YKFK+emCPOEibLeCrg==}
+
+ micromark-extension-gfm-autolink-literal@2.1.0:
+ resolution: {integrity: sha512-oOg7knzhicgQ3t4QCjCWgTmfNhvQbDDnJeVu9v81r7NltNCVmhPy1fJRX27pISafdjL+SVc4d3l48Gb6pbRypw==}
+
+ micromark-extension-gfm-footnote@2.1.0:
+ resolution: {integrity: sha512-/yPhxI1ntnDNsiHtzLKYnE3vf9JZ6cAisqVDauhp4CEHxlb4uoOTxOCJ+9s51bIB8U1N1FJ1RXOKTIlD5B/gqw==}
+
+ micromark-extension-gfm-strikethrough@2.1.0:
+ resolution: {integrity: sha512-ADVjpOOkjz1hhkZLlBiYA9cR2Anf8F4HqZUO6e5eDcPQd0Txw5fxLzzxnEkSkfnD0wziSGiv7sYhk/ktvbf1uw==}
+
+ micromark-extension-gfm-table@2.1.1:
+ resolution: {integrity: sha512-t2OU/dXXioARrC6yWfJ4hqB7rct14e8f7m0cbI5hUmDyyIlwv5vEtooptH8INkbLzOatzKuVbQmAYcbWoyz6Dg==}
+
+ micromark-extension-gfm-tagfilter@2.0.0:
+ resolution: {integrity: sha512-xHlTOmuCSotIA8TW1mDIM6X2O1SiX5P9IuDtqGonFhEK0qgRI4yeC6vMxEV2dgyr2TiD+2PQ10o+cOhdVAcwfg==}
+
+ micromark-extension-gfm-task-list-item@2.1.0:
+ resolution: {integrity: sha512-qIBZhqxqI6fjLDYFTBIa4eivDMnP+OZqsNwmQ3xNLE4Cxwc+zfQEfbs6tzAo2Hjq+bh6q5F+Z8/cksrLFYWQQw==}
+
+ micromark-extension-gfm@3.0.0:
+ resolution: {integrity: sha512-vsKArQsicm7t0z2GugkCKtZehqUm31oeGBV/KVSorWSy8ZlNAv7ytjFhvaryUiCUJYqs+NoE6AFhpQvBTM6Q4w==}
+
+ micromark-factory-destination@2.0.1:
+ resolution: {integrity: sha512-Xe6rDdJlkmbFRExpTOmRj9N3MaWmbAgdpSrBQvCFqhezUn4AHqJHbaEnfbVYYiexVSs//tqOdY/DxhjdCiJnIA==}
+
+ micromark-factory-label@2.0.1:
+ resolution: {integrity: sha512-VFMekyQExqIW7xIChcXn4ok29YE3rnuyveW3wZQWWqF4Nv9Wk5rgJ99KzPvHjkmPXF93FXIbBp6YdW3t71/7Vg==}
+
+ micromark-factory-space@2.0.1:
+ resolution: {integrity: sha512-zRkxjtBxxLd2Sc0d+fbnEunsTj46SWXgXciZmHq0kDYGnck/ZSGj9/wULTV95uoeYiK5hRXP2mJ98Uo4cq/LQg==}
+
+ micromark-factory-title@2.0.1:
+ resolution: {integrity: sha512-5bZ+3CjhAd9eChYTHsjy6TGxpOFSKgKKJPJxr293jTbfry2KDoWkhBb6TcPVB4NmzaPhMs1Frm9AZH7OD4Cjzw==}
+
+ micromark-factory-whitespace@2.0.1:
+ resolution: {integrity: sha512-Ob0nuZ3PKt/n0hORHyvoD9uZhr+Za8sFoP+OnMcnWK5lngSzALgQYKMr9RJVOWLqQYuyn6ulqGWSXdwf6F80lQ==}
+
+ micromark-util-character@2.1.1:
+ resolution: {integrity: sha512-wv8tdUTJ3thSFFFJKtpYKOYiGP2+v96Hvk4Tu8KpCAsTMs6yi+nVmGh1syvSCsaxz45J6Jbw+9DD6g97+NV67Q==}
+
+ micromark-util-chunked@2.0.1:
+ resolution: {integrity: sha512-QUNFEOPELfmvv+4xiNg2sRYeS/P84pTW0TCgP5zc9FpXetHY0ab7SxKyAQCNCc1eK0459uoLI1y5oO5Vc1dbhA==}
+
+ micromark-util-classify-character@2.0.1:
+ resolution: {integrity: sha512-K0kHzM6afW/MbeWYWLjoHQv1sgg2Q9EccHEDzSkxiP/EaagNzCm7T/WMKZ3rjMbvIpvBiZgwR3dKMygtA4mG1Q==}
+
+ micromark-util-combine-extensions@2.0.1:
+ resolution: {integrity: sha512-OnAnH8Ujmy59JcyZw8JSbK9cGpdVY44NKgSM7E9Eh7DiLS2E9RNQf0dONaGDzEG9yjEl5hcqeIsj4hfRkLH/Bg==}
+
+ micromark-util-decode-numeric-character-reference@2.0.2:
+ resolution: {integrity: sha512-ccUbYk6CwVdkmCQMyr64dXz42EfHGkPQlBj5p7YVGzq8I7CtjXZJrubAYezf7Rp+bjPseiROqe7G6foFd+lEuw==}
+
+ micromark-util-decode-string@2.0.1:
+ resolution: {integrity: sha512-nDV/77Fj6eH1ynwscYTOsbK7rR//Uj0bZXBwJZRfaLEJ1iGBR6kIfNmlNqaqJf649EP0F3NWNdeJi03elllNUQ==}
+
+ micromark-util-encode@2.0.1:
+ resolution: {integrity: sha512-c3cVx2y4KqUnwopcO9b/SCdo2O67LwJJ/UyqGfbigahfegL9myoEFoDYZgkT7f36T0bLrM9hZTAaAyH+PCAXjw==}
+
+ micromark-util-html-tag-name@2.0.1:
+ resolution: {integrity: sha512-2cNEiYDhCWKI+Gs9T0Tiysk136SnR13hhO8yW6BGNyhOC4qYFnwF1nKfD3HFAIXA5c45RrIG1ub11GiXeYd1xA==}
+
+ micromark-util-normalize-identifier@2.0.1:
+ resolution: {integrity: sha512-sxPqmo70LyARJs0w2UclACPUUEqltCkJ6PhKdMIDuJ3gSf/Q+/GIe3WKl0Ijb/GyH9lOpUkRAO2wp0GVkLvS9Q==}
+
+ micromark-util-resolve-all@2.0.1:
+ resolution: {integrity: sha512-VdQyxFWFT2/FGJgwQnJYbe1jjQoNTS4RjglmSjTUlpUMa95Htx9NHeYW4rGDJzbjvCsl9eLjMQwGeElsqmzcHg==}
+
+ micromark-util-sanitize-uri@2.0.1:
+ resolution: {integrity: sha512-9N9IomZ/YuGGZZmQec1MbgxtlgougxTodVwDzzEouPKo3qFWvymFHWcnDi2vzV1ff6kas9ucW+o3yzJK9YB1AQ==}
+
+ micromark-util-subtokenize@2.1.0:
+ resolution: {integrity: sha512-XQLu552iSctvnEcgXw6+Sx75GflAPNED1qx7eBJ+wydBb2KCbRZe+NwvIEEMM83uml1+2WSXpBAcp9IUCgCYWA==}
+
+ micromark-util-symbol@2.0.1:
+ resolution: {integrity: sha512-vs5t8Apaud9N28kgCrRUdEed4UJ+wWNvicHLPxCa9ENlYuAY31M0ETy5y1vA33YoNPDFTghEbnh6efaE8h4x0Q==}
+
+ micromark-util-types@2.0.2:
+ resolution: {integrity: sha512-Yw0ECSpJoViF1qTU4DC6NwtC4aWGt1EkzaQB8KPPyCRR8z9TWeV0HbEFGTO+ZY1wB22zmxnJqhPyTpOVCpeHTA==}
+
+ micromark@4.0.2:
+ resolution: {integrity: sha512-zpe98Q6kvavpCr1NPVSCMebCKfD7CA2NqZ+rykeNhONIJBpc1tFKt9hucLGwha3jNTNI8lHpctWJWoimVF4PfA==}
+
+ mime-db@1.52.0:
+ resolution: {integrity: sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==}
+ engines: {node: '>= 0.6'}
+
+ mime-types@2.1.35:
+ resolution: {integrity: sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==}
+ engines: {node: '>= 0.6'}
+
+ min-indent@1.0.1:
+ resolution: {integrity: sha512-I9jwMn07Sy/IwOj3zVkVik2JTvgpaykDZEigL6Rx6N9LbMywwUSMtxET+7lVoDLLd3O3IXwJwvuuns8UB/HeAg==}
+ engines: {node: '>=4'}
+
+ minimist@1.2.8:
+ resolution: {integrity: sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==}
+
+ minipass@7.1.3:
+ resolution: {integrity: sha512-tEBHqDnIoM/1rXME1zgka9g6Q2lcoCkxHLuc7ODJ5BxbP5d4c2Z5cGgtXAku59200Cx7diuHTOYfSBD8n6mm8A==}
+ engines: {node: '>=16 || 14 >=14.17'}
+
+ minizlib@3.1.0:
+ resolution: {integrity: sha512-KZxYo1BUkWD2TVFLr0MQoM8vUUigWD3LlD83a/75BqC+4qE0Hb1Vo5v1FgcfaNXvfXzr+5EhQ6ing/CaBijTlw==}
+ engines: {node: '>= 18'}
+
+ mlly@1.8.2:
+ resolution: {integrity: sha512-d+ObxMQFmbt10sretNDytwt85VrbkhhUA/JBGm1MPaWJ65Cl4wOgLaB1NYvJSZ0Ef03MMEU/0xpPMXUIQ29UfA==}
+
+ moment@2.30.1:
+ resolution: {integrity: sha512-uEmtNhbDOrWPFS+hdjFCBfy9f2YoyzRpwcl+DqpC6taX21FzsTLQVbMV/W7PzNSX6x/bhC1zA3c2UQ5NzH6how==}
+
+ mrmime@2.0.1:
+ resolution: {integrity: sha512-Y3wQdFg2Va6etvQ5I82yUhGdsKrcYox6p7FfL1LbK2J4V01F9TGlepTIhnK24t7koZibmg82KGglhA1XK5IsLQ==}
+ engines: {node: '>=10'}
+
+ ms@2.1.3:
+ resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==}
+
+ muggle-string@0.4.1:
+ resolution: {integrity: sha512-VNTrAak/KhO2i8dqqnqnAHOa3cYBwXEZe9h+D5h/1ZqFSTEFHdM65lR7RoIqq3tBBYavsOXV84NoHXZ0AkPyqQ==}
+
+ nanoid@3.3.11:
+ resolution: {integrity: sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==}
+ engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1}
+ hasBin: true
+
+ neotraverse@0.6.18:
+ resolution: {integrity: sha512-Z4SmBUweYa09+o6pG+eASabEpP6QkQ70yHj351pQoEXIs8uHbaU2DWVmzBANKgflPa47A50PtB2+NgRpQvr7vA==}
+ engines: {node: '>= 10'}
+
+ nlcst-to-string@4.0.0:
+ resolution: {integrity: sha512-YKLBCcUYKAg0FNlOBT6aI91qFmSiFKiluk655WzPF+DDMA02qIyy8uiRqI8QXtcFpEvll12LpL5MXqEmAZ+dcA==}
+
+ node-fetch-native@1.6.7:
+ resolution: {integrity: sha512-g9yhqoedzIUm0nTnTqAQvueMPVOuIY16bqgAJJC8XOOubYFNwz6IER9qs0Gq2Xd0+CecCKFjtdDTMA4u4xG06Q==}
+
+ node-mock-http@1.0.4:
+ resolution: {integrity: sha512-8DY+kFsDkNXy1sJglUfuODx1/opAGJGyrTuFqEoN90oRc2Vk0ZbD4K2qmKXBBEhZQzdKHIVfEJpDU8Ak2NJEvQ==}
+
+ node-releases@2.0.36:
+ resolution: {integrity: sha512-TdC8FSgHz8Mwtw9g5L4gR/Sh9XhSP/0DEkQxfEFXOpiul5IiHgHan2VhYYb6agDSfp4KuvltmGApc8HMgUrIkA==}
+
+ normalize-path@3.0.0:
+ resolution: {integrity: sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==}
+ engines: {node: '>=0.10.0'}
+
+ nth-check@2.1.1:
+ resolution: {integrity: sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w==}
+
+ object-inspect@1.13.4:
+ resolution: {integrity: sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew==}
+ engines: {node: '>= 0.4'}
+
+ obug@2.1.1:
+ resolution: {integrity: sha512-uTqF9MuPraAQ+IsnPf366RG4cP9RtUi7MLO1N3KEc+wb0a6yKpeL0lmk2IB1jY5KHPAlTc6T/JRdC/YqxHNwkQ==}
+
+ ofetch@1.5.1:
+ resolution: {integrity: sha512-2W4oUZlVaqAPAil6FUg/difl6YhqhUR7x2eZY4bQCko22UXg3hptq9KLQdqFClV+Wu85UX7hNtdGTngi/1BxcA==}
+
+ ohash@2.0.11:
+ resolution: {integrity: sha512-RdR9FQrFwNBNXAr4GixM8YaRZRJ5PUWbKYbE5eOsrwAjJW0q2REGcf79oYPsLyskQCZG1PLN+S/K1V00joZAoQ==}
+
+ once@1.4.0:
+ resolution: {integrity: sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==}
+
+ oniguruma-parser@0.12.1:
+ resolution: {integrity: sha512-8Unqkvk1RYc6yq2WBYRj4hdnsAxVze8i7iPfQr8e4uSP3tRv0rpZcbGUDvxfQQcdwHt/e9PrMvGCsa8OqG9X3w==}
+
+ oniguruma-to-es@4.3.5:
+ resolution: {integrity: sha512-Zjygswjpsewa0NLTsiizVuMQZbp0MDyM6lIt66OxsF21npUDlzpHi1Mgb/qhQdkb+dWFTzJmFbEWdvZgRho8eQ==}
+
+ oxfmt@0.41.0:
+ resolution: {integrity: sha512-sKLdJZdQ3bw6x9qKiT7+eID4MNEXlDHf5ZacfIircrq6Qwjk0L6t2/JQlZZrVHTXJawK3KaMuBoJnEJPcqCEdg==}
+ engines: {node: ^20.19.0 || >=22.12.0}
+ hasBin: true
+
+ oxlint@1.56.0:
+ resolution: {integrity: sha512-Q+5Mj5PVaH/R6/fhMMFzw4dT+KPB+kQW4kaL8FOIq7tfhlnEVp6+3lcWqFruuTNlUo9srZUW3qH7Id4pskeR6g==}
+ engines: {node: ^20.19.0 || >=22.12.0}
+ hasBin: true
+ peerDependencies:
+ oxlint-tsgolint: '>=0.15.0'
+ peerDependenciesMeta:
+ oxlint-tsgolint:
+ optional: true
+
+ p-limit@7.3.0:
+ resolution: {integrity: sha512-7cIXg/Z0M5WZRblrsOla88S4wAK+zOQQWeBYfV3qJuJXMr+LnbYjaadrFaS0JILfEDPVqHyKnZ1Z/1d6J9VVUw==}
+ engines: {node: '>=20'}
+
+ p-queue@9.1.0:
+ resolution: {integrity: sha512-O/ZPaXuQV29uSLbxWBGGZO1mCQXV2BLIwUr59JUU9SoH76mnYvtms7aafH/isNSNGwuEfP6W/4xD0/TJXxrizw==}
+ engines: {node: '>=20'}
+
+ p-timeout@7.0.1:
+ resolution: {integrity: sha512-AxTM2wDGORHGEkPCt8yqxOTMgpfbEHqF51f/5fJCmwFC3C/zNcGT63SymH2ttOAaiIws2zVg4+izQCjrakcwHg==}
+ engines: {node: '>=20'}
+
+ package-manager-detector@1.6.0:
+ resolution: {integrity: sha512-61A5ThoTiDG/C8s8UMZwSorAGwMJ0ERVGj2OjoW5pAalsNOg15+iQiPzrLJ4jhZ1HJzmC2PIHT2oEiH3R5fzNA==}
+
+ parent-module@1.0.1:
+ resolution: {integrity: sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==}
+ engines: {node: '>=6'}
+
+ parse-cache-control@1.0.1:
+ resolution: {integrity: sha512-60zvsJReQPX5/QP0Kzfd/VrpjScIQ7SHBW6bFCYfEP+fp0Eppr1SHhIO5nd1PjZtvclzSzES9D/p5nFJurwfWg==}
+
+ parse-json@5.2.0:
+ resolution: {integrity: sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==}
+ engines: {node: '>=8'}
+
+ parse-latin@7.0.0:
+ resolution: {integrity: sha512-mhHgobPPua5kZ98EF4HWiH167JWBfl4pvAIXXdbaVohtK7a6YBOy56kvhCqduqyo/f3yrHFWmqmiMg/BkBkYYQ==}
+
+ parse5-htmlparser2-tree-adapter@7.1.0:
+ resolution: {integrity: sha512-ruw5xyKs6lrpo9x9rCZqZZnIUntICjQAd0Wsmp396Ul9lN/h+ifgVV1x1gZHi8euej6wTfpqX8j+BFQxF0NS/g==}
+
+ parse5-parser-stream@7.1.2:
+ resolution: {integrity: sha512-JyeQc9iwFLn5TbvvqACIF/VXG6abODeB3Fwmv/TGdLk2LfbWkaySGY72at4+Ty7EkPZj854u4CrICqNk2qIbow==}
+
+ parse5@7.3.0:
+ resolution: {integrity: sha512-IInvU7fabl34qmi9gY8XOVxhYyMyuH2xUNpb2q8/Y+7552KlejkRvqvD19nMoUW/uQGGbqNpA6Tufu5FL5BZgw==}
+
+ parse5@8.0.0:
+ resolution: {integrity: sha512-9m4m5GSgXjL4AjumKzq1Fgfp3Z8rsvjRNbnkVwfu2ImRqE5D0LnY2QfDen18FSY9C573YU5XxSapdHZTZ2WolA==}
+
+ path-browserify@1.0.1:
+ resolution: {integrity: sha512-b7uo2UCUOYZcnF/3ID0lulOJi/bafxa1xPe7ZPsammBSpjSWQkjNxlt635YGS2MiR9GjvuXCtz2emr3jbsz98g==}
+
+ pathe@2.0.3:
+ resolution: {integrity: sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w==}
+
+ pend@1.2.0:
+ resolution: {integrity: sha512-F3asv42UuXchdzt+xXqfW1OGlVBe+mxa2mqI0pg5yAHZPvFmY3Y6drSf/GQ1A86WgWEN9Kzh/WrgKa6iGcHXLg==}
+
+ piccolore@0.1.3:
+ resolution: {integrity: sha512-o8bTeDWjE086iwKrROaDf31K0qC/BENdm15/uH9usSC/uZjJOKb2YGiVHfLY4GhwsERiPI1jmwI2XrA7ACOxVw==}
+
+ picocolors@1.1.1:
+ resolution: {integrity: sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==}
+
+ picomatch@2.3.1:
+ resolution: {integrity: sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==}
+ engines: {node: '>=8.6'}
+
+ picomatch@4.0.3:
+ resolution: {integrity: sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==}
+ engines: {node: '>=12'}
+
+ pkg-types@1.3.1:
+ resolution: {integrity: sha512-/Jm5M4RvtBFVkKWRu2BLUTNP8/M2a+UwuAX+ae4770q1qVGtfjG+WTCupoZixokjmHiry8uI+dlY8KXYV5HVVQ==}
+
+ pkg-types@2.3.0:
+ resolution: {integrity: sha512-SIqCzDRg0s9npO5XQ3tNZioRY1uK06lA41ynBC1YmFTmnY6FjUjVt6s4LoADmwoig1qqD0oK8h1p/8mlMx8Oig==}
+
+ playwright-core@1.58.2:
+ resolution: {integrity: sha512-yZkEtftgwS8CsfYo7nm0KE8jsvm6i/PTgVtB8DL726wNf6H2IMsDuxCpJj59KDaxCtSnrWan2AeDqM7JBaultg==}
+ engines: {node: '>=18'}
+ hasBin: true
+
+ playwright@1.58.2:
+ resolution: {integrity: sha512-vA30H8Nvkq/cPBnNw4Q8TWz1EJyqgpuinBcHET0YVJVFldr8JDNiU9LaWAE1KqSkRYazuaBhTpB5ZzShOezQ6A==}
+ engines: {node: '>=18'}
+ hasBin: true
+
+ postcss-value-parser@4.2.0:
+ resolution: {integrity: sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==}
+
+ postcss@8.5.8:
+ resolution: {integrity: sha512-OW/rX8O/jXnm82Ey1k44pObPtdblfiuWnrd8X7GJ7emImCOstunGbXUpp7HdBrFQX6rJzn3sPT397Wp5aCwCHg==}
+ engines: {node: ^10 || ^12 || >=14}
+
+ prettier@3.8.1:
+ resolution: {integrity: sha512-UOnG6LftzbdaHZcKoPFtOcCKztrQ57WkHDeRD9t/PTQtmT0NHSeWWepj6pS0z/N7+08BHFDQVUrfmfMRcZwbMg==}
+ engines: {node: '>=14'}
+ hasBin: true
+
+ prismjs@1.30.0:
+ resolution: {integrity: sha512-DEvV2ZF2r2/63V+tK8hQvrR2ZGn10srHbXviTlcv7Kpzw8jWiNTqbVgjO3IY8RxrrOUF8VPMQQFysYYYv0YZxw==}
+ engines: {node: '>=6'}
+
+ process-nextick-args@2.0.1:
+ resolution: {integrity: sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==}
+
+ promise@8.3.0:
+ resolution: {integrity: sha512-rZPNPKTOYVNEEKFaq1HqTgOwZD+4/YHS5ukLzQCypkj+OkYx7iv0mA91lJlpPPZ8vMau3IIGj5Qlwrx+8iiSmg==}
+
+ property-information@7.1.0:
+ resolution: {integrity: sha512-TwEZ+X+yCJmYfL7TPUOcvBZ4QfoT5YenQiJuX//0th53DE6w0xxLEtfK3iyryQFddXuvkIk51EEgrJQ0WJkOmQ==}
+
+ pump@3.0.4:
+ resolution: {integrity: sha512-VS7sjc6KR7e1ukRFhQSY5LM2uBWAUPiOPa/A3mkKmiMwSmRFUITt0xuj+/lesgnCv+dPIEYlkzrcyXgquIHMcA==}
+
+ punycode@2.3.1:
+ resolution: {integrity: sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==}
+ engines: {node: '>=6'}
+
+ qs@6.15.0:
+ resolution: {integrity: sha512-mAZTtNCeetKMH+pSjrb76NAM8V9a05I9aBZOHztWy/UqcJdQYNsf59vrRKWnojAT9Y+GbIvoTBC++CPHqpDBhQ==}
+ engines: {node: '>=0.6'}
+
+ quansync@0.2.11:
+ resolution: {integrity: sha512-AifT7QEbW9Nri4tAwR5M/uzpBuqfZf+zwaEM/QkzEjj7NBuFD2rBuy0K3dE+8wltbezDV7JMA0WfnCPYRSYbXA==}
+
+ radix3@1.1.2:
+ resolution: {integrity: sha512-b484I/7b8rDEdSDKckSSBA8knMpcdsXudlE/LNL639wFoHKwLbEkQFZHWEYwDC0wa0FKUcCY+GAF73Z7wxNVFA==}
+
+ react-dom@19.2.4:
+ resolution: {integrity: sha512-AXJdLo8kgMbimY95O2aKQqsz2iWi9jMgKJhRBAxECE4IFxfcazB2LmzloIoibJI3C12IlY20+KFaLv+71bUJeQ==}
+ peerDependencies:
+ react: ^19.2.4
+
+ react@19.2.4:
+ resolution: {integrity: sha512-9nfp2hYpCwOjAN+8TZFGhtWEwgvWHXqESH8qT89AT/lWklpLON22Lc8pEtnpsZz7VmawabSU0gCjnj8aC0euHQ==}
+ engines: {node: '>=0.10.0'}
+
+ readable-stream@2.3.8:
+ resolution: {integrity: sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==}
+
+ readdirp@4.1.2:
+ resolution: {integrity: sha512-GDhwkLfywWL2s6vEjyhri+eXmfH6j1L7JE27WhqLeYzoh/A3DBaYGEj2H/HFZCn/kMfim73FXxEJTw06WtxQwg==}
+ engines: {node: '>= 14.18.0'}
+
+ readdirp@5.0.0:
+ resolution: {integrity: sha512-9u/XQ1pvrQtYyMpZe7DXKv2p5CNvyVwzUB6uhLAnQwHMSgKMBR62lc7AHljaeteeHXn11XTAaLLUVZYVZyuRBQ==}
+ engines: {node: '>= 20.19.0'}
+
+ redent@3.0.0:
+ resolution: {integrity: sha512-6tDA8g98We0zd0GvVeMT9arEOnTw9qM03L9cJXaCjrip1OO764RDBLBfrB4cwzNGDj5OA5ioymC9GkizgWJDUg==}
+ engines: {node: '>=8'}
+
+ regex-recursion@6.0.2:
+ resolution: {integrity: sha512-0YCaSCq2VRIebiaUviZNs0cBz1kg5kVS2UKUfNIx8YVs1cN3AV7NTctO5FOKBA+UT2BPJIWZauYHPqJODG50cg==}
+
+ regex-utilities@2.3.0:
+ resolution: {integrity: sha512-8VhliFJAWRaUiVvREIiW2NXXTmHs4vMNnSzuJVhscgmGav3g9VDxLrQndI3dZZVVdp0ZO/5v0xmX516/7M9cng==}
+
+ regex@6.1.0:
+ resolution: {integrity: sha512-6VwtthbV4o/7+OaAF9I5L5V3llLEsoPyq9P1JVXkedTP33c7MfCG0/5NOPcSJn0TzXcG9YUrR0gQSWioew3LDg==}
+
+ rehype-parse@9.0.1:
+ resolution: {integrity: sha512-ksCzCD0Fgfh7trPDxr2rSylbwq9iYDkSn8TCDmEJ49ljEUBxDVCzCHv7QNzZOfODanX4+bWQ4WZqLCRWYLfhag==}
+
+ rehype-raw@7.0.0:
+ resolution: {integrity: sha512-/aE8hCfKlQeA8LmyeyQvQF3eBiLRGNlfBJEvWH7ivp9sBqs7TNqBL5X3v157rM4IFETqDnIOO+z5M/biZbo9Ww==}
+
+ rehype-stringify@10.0.1:
+ resolution: {integrity: sha512-k9ecfXHmIPuFVI61B9DeLPN0qFHfawM6RsuX48hoqlaKSF61RskNjSm1lI8PhBEM0MRdLxVVm4WmTqJQccH9mA==}
+
+ rehype@13.0.2:
+ resolution: {integrity: sha512-j31mdaRFrwFRUIlxGeuPXXKWQxet52RBQRvCmzl5eCefn/KGbomK5GMHNMsOJf55fgo3qw5tST5neDuarDYR2A==}
+
+ remark-gfm@4.0.1:
+ resolution: {integrity: sha512-1quofZ2RQ9EWdeN34S79+KExV1764+wCUGop5CPL1WGdD0ocPpu91lzPGbwWMECpEpd42kJGQwzRfyov9j4yNg==}
+
+ remark-parse@11.0.0:
+ resolution: {integrity: sha512-FCxlKLNGknS5ba/1lmpYijMUzX2esxW5xQqjWxw2eHFfS2MSdaHVINFmhjo+qN1WhZhNimq0dZATN9pH0IDrpA==}
+
+ remark-rehype@11.1.2:
+ resolution: {integrity: sha512-Dh7l57ianaEoIpzbp0PC9UKAdCSVklD8E5Rpw7ETfbTl3FqcOOgq5q2LVDhgGCkaBv7p24JXikPdvhhmHvKMsw==}
+
+ remark-smartypants@3.0.2:
+ resolution: {integrity: sha512-ILTWeOriIluwEvPjv67v7Blgrcx+LZOkAUVtKI3putuhlZm84FnqDORNXPPm+HY3NdZOMhyDwZ1E+eZB/Df5dA==}
+ engines: {node: '>=16.0.0'}
+
+ remark-stringify@11.0.0:
+ resolution: {integrity: sha512-1OSmLd3awB/t8qdoEOMazZkNsfVTeY4fTsgzcQFdXNq8ToTN4ZGwrMnlda4K6smTFKD+GRV6O48i6Z4iKgPPpw==}
+
+ request-light@0.5.8:
+ resolution: {integrity: sha512-3Zjgh+8b5fhRJBQZoy+zbVKpAQGLyka0MPgW3zruTF4dFFJ8Fqcfu9YsAvi/rvdcaTeWG3MkbZv4WKxAn/84Lg==}
+
+ request-light@0.7.0:
+ resolution: {integrity: sha512-lMbBMrDoxgsyO+yB3sDcrDuX85yYt7sS8BfQd11jtbW/z5ZWgLZRcEGLsLoYw7I0WSUGQBs8CC8ScIxkTX1+6Q==}
+
+ require-directory@2.1.1:
+ resolution: {integrity: sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==}
+ engines: {node: '>=0.10.0'}
+
+ require-from-string@2.0.2:
+ resolution: {integrity: sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==}
+ engines: {node: '>=0.10.0'}
+
+ resolve-from@4.0.0:
+ resolution: {integrity: sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==}
+ engines: {node: '>=4'}
+
+ resolve-from@5.0.0:
+ resolution: {integrity: sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==}
+ engines: {node: '>=8'}
+
+ retext-latin@4.0.0:
+ resolution: {integrity: sha512-hv9woG7Fy0M9IlRQloq/N6atV82NxLGveq+3H2WOi79dtIYWN8OaxogDm77f8YnVXJL2VD3bbqowu5E3EMhBYA==}
+
+ retext-smartypants@6.2.0:
+ resolution: {integrity: sha512-kk0jOU7+zGv//kfjXEBjdIryL1Acl4i9XNkHxtM7Tm5lFiCog576fjNC9hjoR7LTKQ0DsPWy09JummSsH1uqfQ==}
+
+ retext-stringify@4.0.0:
+ resolution: {integrity: sha512-rtfN/0o8kL1e+78+uxPTqu1Klt0yPzKuQ2BfWwwfgIUSayyzxpM1PJzkKt4V8803uB9qSy32MvI7Xep9khTpiA==}
+
+ retext@9.0.0:
+ resolution: {integrity: sha512-sbMDcpHCNjvlheSgMfEcVrZko3cDzdbe1x/e7G66dFp0Ff7Mldvi2uv6JkJQzdRcvLYE8CA8Oe8siQx8ZOgTcA==}
+
+ rollup@4.60.0:
+ resolution: {integrity: sha512-yqjxruMGBQJ2gG4HtjZtAfXArHomazDHoFwFFmZZl0r7Pdo7qCIXKqKHZc8yeoMgzJJ+pO6pEEHa+V7uzWlrAQ==}
+ engines: {node: '>=18.0.0', npm: '>=8.0.0'}
+ hasBin: true
+
+ rss-parser@3.13.0:
+ resolution: {integrity: sha512-7jWUBV5yGN3rqMMj7CZufl/291QAhvrrGpDNE4k/02ZchL0npisiYYqULF71jCEKoIiHvK/Q2e6IkDwPziT7+w==}
+
+ safe-buffer@5.1.2:
+ resolution: {integrity: sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==}
+
+ safe-buffer@5.2.1:
+ resolution: {integrity: sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==}
+
+ safer-buffer@2.1.2:
+ resolution: {integrity: sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==}
+
+ sax@1.6.0:
+ resolution: {integrity: sha512-6R3J5M4AcbtLUdZmRv2SygeVaM7IhrLXu9BmnOGmmACak8fiUtOsYNWUS4uK7upbmHIBbLBeFeI//477BKLBzA==}
+ engines: {node: '>=11.0.0'}
+
+ saxes@6.0.0:
+ resolution: {integrity: sha512-xAg7SOnEhrm5zI3puOOKyy1OMcMlIJZYNJY7xLBwSze0UjhPLnWfj2GF2EpT0jmzaJKIWKHLsaSSajf35bcYnA==}
+ engines: {node: '>=v12.22.7'}
+
+ scheduler@0.27.0:
+ resolution: {integrity: sha512-eNv+WrVbKu1f3vbYJT/xtiF5syA5HPIMtf9IgY/nKg0sWqzAUEvqY/xm7OcZc/qafLx/iO9FgOmeSAp4v5ti/Q==}
+
+ semver@7.7.4:
+ resolution: {integrity: sha512-vFKC2IEtQnVhpT78h1Yp8wzwrf8CM+MzKMHGJZfBtzhZNycRFnXsHk6E5TxIkkMsgNS7mdX3AGB7x2QM2di4lA==}
+ engines: {node: '>=10'}
+ hasBin: true
+
+ shaders@2.4.78:
+ resolution: {integrity: sha512-e+agxQwPhjkpKcJ86tiv5exktKercAexwXg7fWuyVpKdnsJPGeXZxiFnf7CsATmIy+oKf+DNEgbJCI14osD0PQ==}
+ peerDependencies:
+ pixi.js: ^8.0.0
+ react: ^18.0.0 || ^19.0.0
+ react-dom: ^18.0.0 || ^19.0.0
+ solid-js: ^1.8.0
+ svelte: ^5
+ vue: ^3.0.0
+ peerDependenciesMeta:
+ pixi.js:
+ optional: true
+ react:
+ optional: true
+ react-dom:
+ optional: true
+ solid-js:
+ optional: true
+ svelte:
+ optional: true
+ vue:
+ optional: true
+
+ sharp@0.34.5:
+ resolution: {integrity: sha512-Ou9I5Ft9WNcCbXrU9cMgPBcCK8LiwLqcbywW3t4oDV37n1pzpuNLsYiAV8eODnjbtQlSDwZ2cUEeQz4E54Hltg==}
+ engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
+
+ shiki@4.0.2:
+ resolution: {integrity: sha512-eAVKTMedR5ckPo4xne/PjYQYrU3qx78gtJZ+sHlXEg5IHhhoQhMfZVzetTYuaJS0L2Ef3AcCRzCHV8T0WI6nIQ==}
+ engines: {node: '>=20'}
+
+ side-channel-list@1.0.0:
+ resolution: {integrity: sha512-FCLHtRD/gnpCiCHEiJLOwdmFP+wzCmDEkc9y7NsYxeF4u7Btsn1ZuwgwJGxImImHicJArLP4R0yX4c2KCrMrTA==}
+ engines: {node: '>= 0.4'}
+
+ side-channel-map@1.0.1:
+ resolution: {integrity: sha512-VCjCNfgMsby3tTdo02nbjtM/ewra6jPHmpThenkTYh8pG9ucZ/1P8So4u4FGBek/BjpOVsDCMoLA/iuBKIFXRA==}
+ engines: {node: '>= 0.4'}
+
+ side-channel-weakmap@1.0.2:
+ resolution: {integrity: sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A==}
+ engines: {node: '>= 0.4'}
+
+ side-channel@1.1.0:
+ resolution: {integrity: sha512-ZX99e6tRweoUXqR+VBrslhda51Nh5MTQwou5tnUDgbtyM0dBgmhEDtWGP/xbKn6hqfPRHujUNwz5fy/wbbhnpw==}
+ engines: {node: '>= 0.4'}
+
+ siginfo@2.0.0:
+ resolution: {integrity: sha512-ybx0WO1/8bSBLEWXZvEd7gMW3Sn3JFlW3TvX1nREbDLRNQNaeNN8WK0meBwPdAaOI7TtRRRJn/Es1zhrrCHu7g==}
+
+ sirv@3.0.2:
+ resolution: {integrity: sha512-2wcC/oGxHis/BoHkkPwldgiPSYcpZK3JU28WoMVv55yHJgcZ8rlXvuG9iZggz+sU1d4bRgIGASwyWqjxu3FM0g==}
+ engines: {node: '>=18'}
+
+ sisteransi@1.0.5:
+ resolution: {integrity: sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==}
+
+ smol-toml@1.6.1:
+ resolution: {integrity: sha512-dWUG8F5sIIARXih1DTaQAX4SsiTXhInKf1buxdY9DIg4ZYPZK5nGM1VRIYmEbDbsHt7USo99xSLFu5Q1IqTmsg==}
+ engines: {node: '>= 18'}
+
+ source-map-js@1.2.1:
+ resolution: {integrity: sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==}
+ engines: {node: '>=0.10.0'}
+
+ space-separated-tokens@2.0.2:
+ resolution: {integrity: sha512-PEGlAwrG8yXGXRjW32fGbg66JAlOAwbObuqVoJpv/mRgoWDQfgH1wDPvtzWyUSNAXBGSk8h755YDbbcEy3SH2Q==}
+
+ stackback@0.0.2:
+ resolution: {integrity: sha512-1XMJE5fQo1jGH6Y/7ebnwPOBEkIEnT4QF32d5R1+VXdXveM0IBMJt8zfaxX1P3QhVwrYe+576+jkANtSS2mBbw==}
+
+ std-env@4.0.0:
+ resolution: {integrity: sha512-zUMPtQ/HBY3/50VbpkupYHbRroTRZJPRLvreamgErJVys0ceuzMkD44J/QjqhHjOzK42GQ3QZIeFG1OYfOtKqQ==}
+
+ string-width@4.2.3:
+ resolution: {integrity: sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==}
+ engines: {node: '>=8'}
+
+ string_decoder@1.1.1:
+ resolution: {integrity: sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==}
+
+ stringify-entities@4.0.4:
+ resolution: {integrity: sha512-IwfBptatlO+QCJUo19AqvrPNqlVMpW9YEL2LIVY+Rpv2qsjCGxaDLNRgeGsQWJhfItebuJhsGSLjaBbNSQ+ieg==}
+
+ strip-ansi@6.0.1:
+ resolution: {integrity: sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==}
+ engines: {node: '>=8'}
+
+ strip-indent@3.0.0:
+ resolution: {integrity: sha512-laJTa3Jb+VQpaC6DseHhF7dXVqHTfJPCRDaEbid/drOhgitgYku/letMUqOXFoWV0zIIUbjpdH2t+tYj4bQMRQ==}
+ engines: {node: '>=8'}
+
+ supports-color@7.2.0:
+ resolution: {integrity: sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==}
+ engines: {node: '>=8'}
+
+ svgo@3.3.3:
+ resolution: {integrity: sha512-+wn7I4p7YgJhHs38k2TNjy1vCfPIfLIJWR5MnCStsN8WuuTcBnRKcMHQLMM2ijxGZmDoZwNv8ipl5aTTen62ng==}
+ engines: {node: '>=14.0.0'}
+ hasBin: true
+
+ svgo@4.0.1:
+ resolution: {integrity: sha512-XDpWUOPC6FEibaLzjfe0ucaV0YrOjYotGJO1WpF0Zd+n6ZGEQUsSugaoLq9QkEZtAfQIxT42UChcssDVPP3+/w==}
+ engines: {node: '>=16'}
+ hasBin: true
+
+ symbol-tree@3.2.4:
+ resolution: {integrity: sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw==}
+
+ sync-request@6.1.0:
+ resolution: {integrity: sha512-8fjNkrNlNCrVc/av+Jn+xxqfCjYaBoHqCsDz6mt030UMxJGr+GSfCV1dQt2gRtlL63+VPidwDVLr7V2OcTSdRw==}
+ engines: {node: '>=8.0.0'}
+
+ sync-rpc@1.3.6:
+ resolution: {integrity: sha512-J8jTXuZzRlvU7HemDgHi3pGnh/rkoqR/OZSjhTyyZrEkkYQbk7Z33AXp37mkPfPpfdOuj7Ex3H/TJM1z48uPQw==}
+
+ tailwindcss@4.2.2:
+ resolution: {integrity: sha512-KWBIxs1Xb6NoLdMVqhbhgwZf2PGBpPEiwOqgI4pFIYbNTfBXiKYyWoTsXgBQ9WFg/OlhnvHaY+AEpW7wSmFo2Q==}
+
+ tapable@2.3.1:
+ resolution: {integrity: sha512-b+u3CEM6FjDHru+nhUSjDofpWSBp2rINziJWgApm72wwGasQ/wKXftZe4tI2Y5HPv6OpzXSZHOFq87H4vfsgsw==}
+ engines: {node: '>=6'}
+
+ tar@7.5.13:
+ resolution: {integrity: sha512-tOG/7GyXpFevhXVh8jOPJrmtRpOTsYqUIkVdVooZYJS/z8WhfQUX8RJILmeuJNinGAMSu1veBr4asSHFt5/hng==}
+ engines: {node: '>=18'}
+
+ then-request@6.0.2:
+ resolution: {integrity: sha512-3ZBiG7JvP3wbDzA9iNY5zJQcHL4jn/0BWtXIkagfz7QgOL/LqjCEOBQuJNZfu0XYnv5JhKh+cDxCPM4ILrqruA==}
+ engines: {node: '>=6.0.0'}
+
+ three@0.183.2:
+ resolution: {integrity: sha512-di3BsL2FEQ1PA7Hcvn4fyJOlxRRgFYBpMTcyOgkwJIaDOdJMebEFPA+t98EvjuljDx4hNulAGwF6KIjtwI5jgQ==}
+
+ tiny-inflate@1.0.3:
+ resolution: {integrity: sha512-pkY1fj1cKHb2seWDy0B16HeWyczlJA9/WW3u3c4z/NiWDsO3DOU5D7nhTLE9CF0yXv/QZFY7sEJmj24dK+Rrqw==}
+
+ tinybench@2.9.0:
+ resolution: {integrity: sha512-0+DUvqWMValLmha6lr4kD8iAMK1HzV0/aKnCtWb9v9641TnP/MFb7Pc2bxoxQjTXAErryXVgUOfv2YqNllqGeg==}
+
+ tinyclip@0.1.12:
+ resolution: {integrity: sha512-Ae3OVUqifDw0wBriIBS7yVaW44Dp6eSHQcyq4Igc7eN2TJH/2YsicswaW+J/OuMvhpDPOKEgpAZCjkb4hpoyeA==}
+ engines: {node: ^16.14.0 || >= 17.3.0}
+
+ tinyexec@1.0.4:
+ resolution: {integrity: sha512-u9r3uZC0bdpGOXtlxUIdwf9pkmvhqJdrVCH9fapQtgy/OeTTMZ1nqH7agtvEfmGui6e1XxjcdrlxvxJvc3sMqw==}
+ engines: {node: '>=18'}
+
+ tinyglobby@0.2.15:
+ resolution: {integrity: sha512-j2Zq4NyQYG5XMST4cbs02Ak8iJUdxRM0XI5QyxXuZOzKOINmWurp3smXu3y5wDcJrptwpSjgXHzIQxR0omXljQ==}
+ engines: {node: '>=12.0.0'}
+
+ tinypool@2.1.0:
+ resolution: {integrity: sha512-Pugqs6M0m7Lv1I7FtxN4aoyToKg1C4tu+/381vH35y8oENM/Ai7f7C4StcoK4/+BSw9ebcS8jRiVrORFKCALLw==}
+ engines: {node: ^20.0.0 || >=22.0.0}
+
+ tinyrainbow@3.1.0:
+ resolution: {integrity: sha512-Bf+ILmBgretUrdJxzXM0SgXLZ3XfiaUuOj/IKQHuTXip+05Xn+uyEYdVg0kYDipTBcLrCVyUzAPz7QmArb0mmw==}
+ engines: {node: '>=14.0.0'}
+
+ tldts-core@7.0.27:
+ resolution: {integrity: sha512-YQ7uPjgWUibIK6DW5lrKujGwUKhLevU4hcGbP5O6TcIUb+oTjJYJVWPS4nZsIHrEEEG6myk/oqAJUEQmpZrHsg==}
+
+ tldts@7.0.27:
+ resolution: {integrity: sha512-I4FZcVFcqCRuT0ph6dCDpPuO4Xgzvh+spkcTr1gK7peIvxWauoloVO0vuy1FQnijT63ss6AsHB6+OIM4aXHbPg==}
+ hasBin: true
+
+ totalist@3.0.1:
+ resolution: {integrity: sha512-sf4i37nQ2LBx4m3wB74y+ubopq6W/dIzXg0FDGjsYnZHVa1Da8FH853wlL2gtUhg+xJXjfk3kUZS3BRoQeoQBQ==}
+ engines: {node: '>=6'}
+
+ tough-cookie@6.0.1:
+ resolution: {integrity: sha512-LktZQb3IeoUWB9lqR5EWTHgW/VTITCXg4D21M+lvybRVdylLrRMnqaIONLVb5mav8vM19m44HIcGq4qASeu2Qw==}
+ engines: {node: '>=16'}
+
+ tr46@6.0.0:
+ resolution: {integrity: sha512-bLVMLPtstlZ4iMQHpFHTR7GAGj2jxi8Dg0s2h2MafAE4uSWF98FC/3MomU51iQAMf8/qDUbKWf5GxuvvVcXEhw==}
+ engines: {node: '>=20'}
+
+ trim-lines@3.0.1:
+ resolution: {integrity: sha512-kRj8B+YHZCc9kQYdWfJB2/oUl9rA99qbowYYBtr4ui4mZyAQ2JpvVBd/6U2YloATfqBhBTSMhTpgBHtU0Mf3Rg==}
+
+ trough@2.2.0:
+ resolution: {integrity: sha512-tmMpK00BjZiUyVyvrBK7knerNgmgvcV/KLVyuma/SC+TQN167GrMRciANTz09+k3zW8L8t60jWO1GpfkZdjTaw==}
+
+ tsconfck@3.1.6:
+ resolution: {integrity: sha512-ks6Vjr/jEw0P1gmOVwutM3B7fWxoWBL2KRDb1JfqGVawBmO5UsvmWOQFGHBPl5yxYz4eERr19E6L7NMv+Fej4w==}
+ engines: {node: ^18 || >=20}
+ hasBin: true
+ peerDependencies:
+ typescript: ^5.0.0
+ peerDependenciesMeta:
+ typescript:
+ optional: true
+
+ tslib@2.8.1:
+ resolution: {integrity: sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==}
+
+ typedarray@0.0.6:
+ resolution: {integrity: sha512-/aCDEGatGvZ2BIk+HmLf4ifCJFwvKFNb9/JeZPMulfgFracn9QFcAf5GO8B/mweUjSoblS5In0cWhqpfs/5PQA==}
+
+ typesafe-path@0.2.2:
+ resolution: {integrity: sha512-OJabfkAg1WLZSqJAJ0Z6Sdt3utnbzr/jh+NAHoyWHJe8CMSy79Gm085094M9nvTPy22KzTVn5Zq5mbapCI/hPA==}
+
+ typescript-auto-import-cache@0.3.6:
+ resolution: {integrity: sha512-RpuHXrknHdVdK7wv/8ug3Fr0WNsNi5l5aB8MYYuXhq2UH5lnEB1htJ1smhtD5VeCsGr2p8mUDtd83LCQDFVgjQ==}
+
+ typescript@5.9.3:
+ resolution: {integrity: sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==}
+ engines: {node: '>=14.17'}
+ hasBin: true
+
+ ufo@1.6.3:
+ resolution: {integrity: sha512-yDJTmhydvl5lJzBmy/hyOAA0d+aqCBuwl818haVdYCRrWV84o7YyeVm4QlVHStqNrrJSTb6jKuFAVqAFsr+K3Q==}
+
+ ultrahtml@1.6.0:
+ resolution: {integrity: sha512-R9fBn90VTJrqqLDwyMph+HGne8eqY1iPfYhPzZrvKpIfwkWZbcYlfpsb8B9dTvBfpy1/hqAD7Wi8EKfP9e8zdw==}
+
+ uncrypto@0.1.3:
+ resolution: {integrity: sha512-Ql87qFHB3s/De2ClA9e0gsnS6zXG27SkTiSJwjCc9MebbfapQfuPzumMIUMi38ezPZVNFcHI9sUIepeQfw8J8Q==}
+
+ undici-types@7.18.2:
+ resolution: {integrity: sha512-AsuCzffGHJybSaRrmr5eHr81mwJU3kjw6M+uprWvCXiNeN9SOGwQ3Jn8jb8m3Z6izVgknn1R0FTCEAP2QrLY/w==}
+
+ undici@7.24.5:
+ resolution: {integrity: sha512-3IWdCpjgxp15CbJnsi/Y9TCDE7HWVN19j1hmzVhoAkY/+CJx449tVxT5wZc1Gwg8J+P0LWvzlBzxYRnHJ+1i7Q==}
+ engines: {node: '>=20.18.1'}
+
+ unified@11.0.5:
+ resolution: {integrity: sha512-xKvGhPWw3k84Qjh8bI3ZeJjqnyadK+GEFtazSfZv/rKeTkTjOJho6mFqh2SM96iIcZokxiOpg78GazTSg8+KHA==}
+
+ unifont@0.7.4:
+ resolution: {integrity: sha512-oHeis4/xl42HUIeHuNZRGEvxj5AaIKR+bHPNegRq5LV1gdc3jundpONbjglKpihmJf+dswygdMJn3eftGIMemg==}
+
+ unist-util-find-after@5.0.0:
+ resolution: {integrity: sha512-amQa0Ep2m6hE2g72AugUItjbuM8X8cGQnFoHk0pGfrFeT9GZhzN5SW8nRsiGKK7Aif4CrACPENkA6P/Lw6fHGQ==}
+
+ unist-util-is@6.0.1:
+ resolution: {integrity: sha512-LsiILbtBETkDz8I9p1dQ0uyRUWuaQzd/cuEeS1hoRSyW5E5XGmTzlwY1OrNzzakGowI9Dr/I8HVaw4hTtnxy8g==}
+
+ unist-util-modify-children@4.0.0:
+ resolution: {integrity: sha512-+tdN5fGNddvsQdIzUF3Xx82CU9sMM+fA0dLgR9vOmT0oPT2jH+P1nd5lSqfCfXAw+93NhcXNY2qqvTUtE4cQkw==}
+
+ unist-util-position@5.0.0:
+ resolution: {integrity: sha512-fucsC7HjXvkB5R3kTCO7kUjRdrS0BJt3M/FPxmHMBOm8JQi2BsHAHFsy27E0EolP8rp0NzXsJ+jNPyDWvOJZPA==}
+
+ unist-util-remove-position@5.0.0:
+ resolution: {integrity: sha512-Hp5Kh3wLxv0PHj9m2yZhhLt58KzPtEYKQQ4yxfYFEO7EvHwzyDYnduhHnY1mDxoqr7VUwVuHXk9RXKIiYS1N8Q==}
+
+ unist-util-stringify-position@4.0.0:
+ resolution: {integrity: sha512-0ASV06AAoKCDkS2+xw5RXJywruurpbC4JZSm7nr7MOt1ojAzvyyaO+UxZf18j8FCF6kmzCZKcAgN/yu2gm2XgQ==}
+
+ unist-util-visit-children@3.0.0:
+ resolution: {integrity: sha512-RgmdTfSBOg04sdPcpTSD1jzoNBjt9a80/ZCzp5cI9n1qPzLZWF9YdvWGN2zmTumP1HWhXKdUWexjy/Wy/lJ7tA==}
+
+ unist-util-visit-parents@6.0.2:
+ resolution: {integrity: sha512-goh1s1TBrqSqukSc8wrjwWhL0hiJxgA8m4kFxGlQ+8FYQ3C/m11FcTs4YYem7V664AhHVvgoQLk890Ssdsr2IQ==}
+
+ unist-util-visit@5.1.0:
+ resolution: {integrity: sha512-m+vIdyeCOpdr/QeQCu2EzxX/ohgS8KbnPDgFni4dQsfSCtpz8UqDyY5GjRru8PDKuYn7Fq19j1CQ+nJSsGKOzg==}
+
+ unstorage@1.17.4:
+ resolution: {integrity: sha512-fHK0yNg38tBiJKp/Vgsq4j0JEsCmgqH58HAn707S7zGkArbZsVr/CwINoi+nh3h98BRCwKvx1K3Xg9u3VV83sw==}
+ peerDependencies:
+ '@azure/app-configuration': ^1.8.0
+ '@azure/cosmos': ^4.2.0
+ '@azure/data-tables': ^13.3.0
+ '@azure/identity': ^4.6.0
+ '@azure/keyvault-secrets': ^4.9.0
+ '@azure/storage-blob': ^12.26.0
+ '@capacitor/preferences': ^6 || ^7 || ^8
+ '@deno/kv': '>=0.9.0'
+ '@netlify/blobs': ^6.5.0 || ^7.0.0 || ^8.1.0 || ^9.0.0 || ^10.0.0
+ '@planetscale/database': ^1.19.0
+ '@upstash/redis': ^1.34.3
+ '@vercel/blob': '>=0.27.1'
+ '@vercel/functions': ^2.2.12 || ^3.0.0
+ '@vercel/kv': ^1 || ^2 || ^3
+ aws4fetch: ^1.0.20
+ db0: '>=0.2.1'
+ idb-keyval: ^6.2.1
+ ioredis: ^5.4.2
+ uploadthing: ^7.4.4
+ peerDependenciesMeta:
+ '@azure/app-configuration':
+ optional: true
+ '@azure/cosmos':
+ optional: true
+ '@azure/data-tables':
+ optional: true
+ '@azure/identity':
+ optional: true
+ '@azure/keyvault-secrets':
+ optional: true
+ '@azure/storage-blob':
+ optional: true
+ '@capacitor/preferences':
+ optional: true
+ '@deno/kv':
+ optional: true
+ '@netlify/blobs':
+ optional: true
+ '@planetscale/database':
+ optional: true
+ '@upstash/redis':
+ optional: true
+ '@vercel/blob':
+ optional: true
+ '@vercel/functions':
+ optional: true
+ '@vercel/kv':
+ optional: true
+ aws4fetch:
+ optional: true
+ db0:
+ optional: true
+ idb-keyval:
+ optional: true
+ ioredis:
+ optional: true
+ uploadthing:
+ optional: true
+
+ update-browserslist-db@1.2.3:
+ resolution: {integrity: sha512-Js0m9cx+qOgDxo0eMiFGEueWztz+d4+M3rGlmKPT+T4IS/jP4ylw3Nwpu6cpTTP8R1MAC1kF4VbdLt3ARf209w==}
+ hasBin: true
+ peerDependencies:
+ browserslist: '>= 4.21.0'
+
+ util-deprecate@1.0.2:
+ resolution: {integrity: sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==}
+
+ vfile-location@5.0.3:
+ resolution: {integrity: sha512-5yXvWDEgqeiYiBe1lbxYF7UMAIm/IcopxMHrMQDq3nvKcjPKIhZklUKL+AE7J7uApI4kwe2snsK+eI6UTj9EHg==}
+
+ vfile-message@4.0.3:
+ resolution: {integrity: sha512-QTHzsGd1EhbZs4AsQ20JX1rC3cOlt/IWJruk893DfLRr57lcnOeMaWG4K0JrRta4mIJZKth2Au3mM3u03/JWKw==}
+
+ vfile@6.0.3:
+ resolution: {integrity: sha512-KzIbH/9tXat2u30jf+smMwFCsno4wHVdNmzFyL+T/L3UGqqk6JKfVqOFOZEpZSHADH1k40ab6NUIXZq422ov3Q==}
+
+ vite@7.3.1:
+ resolution: {integrity: sha512-w+N7Hifpc3gRjZ63vYBXA56dvvRlNWRczTdmCBBa+CotUzAPf5b7YMdMR/8CQoeYE5LX3W4wj6RYTgonm1b9DA==}
+ engines: {node: ^20.19.0 || >=22.12.0}
+ hasBin: true
+ peerDependencies:
+ '@types/node': ^20.19.0 || >=22.12.0
+ jiti: '>=1.21.0'
+ less: ^4.0.0
+ lightningcss: ^1.21.0
+ sass: ^1.70.0
+ sass-embedded: ^1.70.0
+ stylus: '>=0.54.8'
+ sugarss: ^5.0.0
+ terser: ^5.16.0
+ tsx: ^4.8.1
+ yaml: ^2.4.2
+ peerDependenciesMeta:
+ '@types/node':
+ optional: true
+ jiti:
+ optional: true
+ less:
+ optional: true
+ lightningcss:
+ optional: true
+ sass:
+ optional: true
+ sass-embedded:
+ optional: true
+ stylus:
+ optional: true
+ sugarss:
+ optional: true
+ terser:
+ optional: true
+ tsx:
+ optional: true
+ yaml:
+ optional: true
+
+ vitefu@1.1.2:
+ resolution: {integrity: sha512-zpKATdUbzbsycPFBN71nS2uzBUQiVnFoOrr2rvqv34S1lcAgMKKkjWleLGeiJlZ8lwCXvtWaRn7R3ZC16SYRuw==}
+ peerDependencies:
+ vite: ^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0-beta.0
+ peerDependenciesMeta:
+ vite:
+ optional: true
+
+ vitest@4.1.1:
+ resolution: {integrity: sha512-yF+o4POL41rpAzj5KVILUxm1GCjKnELvaqmU9TLLUbMfDzuN0UpUR9uaDs+mCtjPe+uYPksXDRLQGGPvj1cTmA==}
+ engines: {node: ^20.0.0 || ^22.0.0 || >=24.0.0}
+ hasBin: true
+ peerDependencies:
+ '@edge-runtime/vm': '*'
+ '@opentelemetry/api': ^1.9.0
+ '@types/node': ^20.0.0 || ^22.0.0 || >=24.0.0
+ '@vitest/browser-playwright': 4.1.1
+ '@vitest/browser-preview': 4.1.1
+ '@vitest/browser-webdriverio': 4.1.1
+ '@vitest/ui': 4.1.1
+ happy-dom: '*'
+ jsdom: '*'
+ vite: ^6.0.0 || ^7.0.0 || ^8.0.0
+ peerDependenciesMeta:
+ '@edge-runtime/vm':
+ optional: true
+ '@opentelemetry/api':
+ optional: true
+ '@types/node':
+ optional: true
+ '@vitest/browser-playwright':
+ optional: true
+ '@vitest/browser-preview':
+ optional: true
+ '@vitest/browser-webdriverio':
+ optional: true
+ '@vitest/ui':
+ optional: true
+ happy-dom:
+ optional: true
+ jsdom:
+ optional: true
+
+ volar-service-css@0.0.70:
+ resolution: {integrity: sha512-K1qyOvBpE3rzdAv3e4/6Rv5yizrYPy5R/ne3IWCAzLBuMO4qBMV3kSqWzj6KUVe6S0AnN6wxF7cRkiaKfYMYJw==}
+ peerDependencies:
+ '@volar/language-service': ~2.4.0
+ peerDependenciesMeta:
+ '@volar/language-service':
+ optional: true
+
+ volar-service-emmet@0.0.70:
+ resolution: {integrity: sha512-xi5bC4m/VyE3zy/n2CXspKeDZs3qA41tHLTw275/7dNWM/RqE2z3BnDICQybHIVp/6G1iOQj5c1qXMgQC08TNg==}
+ peerDependencies:
+ '@volar/language-service': ~2.4.0
+ peerDependenciesMeta:
+ '@volar/language-service':
+ optional: true
+
+ volar-service-html@0.0.70:
+ resolution: {integrity: sha512-eR6vCgMdmYAo4n+gcT7DSyBQbwB8S3HZZvSagTf0sxNaD4WppMCFfpqWnkrlGStPKMZvMiejRRVmqsX9dYcTvQ==}
+ peerDependencies:
+ '@volar/language-service': ~2.4.0
+ peerDependenciesMeta:
+ '@volar/language-service':
+ optional: true
+
+ volar-service-prettier@0.0.70:
+ resolution: {integrity: sha512-Z6BCFSpGVCd8BPAsZ785Kce1BGlWd5ODqmqZGVuB14MJvrR4+CYz6cDy4F+igmE1gMifqfvMhdgT8Aud4M5ngg==}
+ peerDependencies:
+ '@volar/language-service': ~2.4.0
+ prettier: ^2.2 || ^3.0
+ peerDependenciesMeta:
+ '@volar/language-service':
+ optional: true
+ prettier:
+ optional: true
+
+ volar-service-typescript-twoslash-queries@0.0.70:
+ resolution: {integrity: sha512-IdD13Z9N2Bu8EM6CM0fDV1E69olEYGHDU25X51YXmq8Y0CmJ2LNj6gOiBJgpS5JGUqFzECVhMNBW7R0sPdRTMQ==}
+ peerDependencies:
+ '@volar/language-service': ~2.4.0
+ peerDependenciesMeta:
+ '@volar/language-service':
+ optional: true
+
+ volar-service-typescript@0.0.70:
+ resolution: {integrity: sha512-l46Bx4cokkUedTd74ojO5H/zqHZJ8SUuyZ0IB8JN4jfRqUM3bQFBHoOwlZCyZmOeO0A3RQNkMnFclxO4c++gsg==}
+ peerDependencies:
+ '@volar/language-service': ~2.4.0
+ peerDependenciesMeta:
+ '@volar/language-service':
+ optional: true
+
+ volar-service-yaml@0.0.70:
+ resolution: {integrity: sha512-0c8bXDBeoATF9F6iPIlOuYTuZAC4c+yi0siQo920u7eiBJk8oQmUmg9cDUbR4+Gl++bvGP4plj3fErbJuPqdcQ==}
+ peerDependencies:
+ '@volar/language-service': ~2.4.0
+ peerDependenciesMeta:
+ '@volar/language-service':
+ optional: true
+
+ vscode-css-languageservice@6.3.10:
+ resolution: {integrity: sha512-eq5N9Er3fC4vA9zd9EFhyBG90wtCCuXgRSpAndaOgXMh1Wgep5lBgRIeDgjZBW9pa+332yC9+49cZMW8jcL3MA==}
+
+ vscode-html-languageservice@5.6.2:
+ resolution: {integrity: sha512-ulCrSnFnfQ16YzvwnYUgEbUEl/ZG7u2eV27YhvLObSHKkb8fw1Z9cgsnUwjTEeDIdJDoTDTDpxuhQwoenoLNMg==}
+
+ vscode-json-languageservice@4.1.8:
+ resolution: {integrity: sha512-0vSpg6Xd9hfV+eZAaYN63xVVMOTmJ4GgHxXnkLCh+9RsQBkWKIghzLhW2B9ebfG+LQQg8uLtsQ2aUKjTgE+QOg==}
+ engines: {npm: '>=7.0.0'}
+
+ vscode-jsonrpc@8.2.0:
+ resolution: {integrity: sha512-C+r0eKJUIfiDIfwJhria30+TYWPtuHJXHtI7J0YlOmKAo7ogxP20T0zxB7HZQIFhIyvoBPwWskjxrvAtfjyZfA==}
+ engines: {node: '>=14.0.0'}
+
+ vscode-languageserver-protocol@3.17.5:
+ resolution: {integrity: sha512-mb1bvRJN8SVznADSGWM9u/b07H7Ecg0I3OgXDuLdn307rl/J3A9YD6/eYOssqhecL27hK1IPZAsaqh00i/Jljg==}
+
+ vscode-languageserver-textdocument@1.0.12:
+ resolution: {integrity: sha512-cxWNPesCnQCcMPeenjKKsOCKQZ/L6Tv19DTRIGuLWe32lyzWhihGVJ/rcckZXJxfdKCFvRLS3fpBIsV/ZGX4zA==}
+
+ vscode-languageserver-types@3.17.5:
+ resolution: {integrity: sha512-Ld1VelNuX9pdF39h2Hgaeb5hEZM2Z3jUrrMgWQAu82jMtZp7p3vJT3BzToKtZI7NgQssZje5o0zryOrhQvzQAg==}
+
+ vscode-languageserver@9.0.1:
+ resolution: {integrity: sha512-woByF3PDpkHFUreUa7Hos7+pUWdeWMXRd26+ZX2A8cFx6v/JPTtd4/uN0/jB6XQHYaOlHbio03NTHCqrgG5n7g==}
+ hasBin: true
+
+ vscode-nls@5.2.0:
+ resolution: {integrity: sha512-RAaHx7B14ZU04EU31pT+rKz2/zSl7xMsfIZuo8pd+KZO6PXtQmpevpq3vxvWNcrGbdmhM/rr5Uw5Mz+NBfhVng==}
+
+ vscode-uri@3.1.0:
+ resolution: {integrity: sha512-/BpdSx+yCQGnCvecbyXdxHDkuk55/G3xwnC0GqY4gmQ3j+A+g8kzzgB4Nk/SINjqn6+waqw3EgbVF2QKExkRxQ==}
+
+ w3c-xmlserializer@5.0.0:
+ resolution: {integrity: sha512-o8qghlI8NZHU1lLPrpi2+Uq7abh4GGPpYANlalzWxyWteJOCsr/P+oPBA49TOLu5FTZO4d3F9MnWJfiMo4BkmA==}
+ engines: {node: '>=18'}
+
+ web-namespaces@2.0.1:
+ resolution: {integrity: sha512-bKr1DkiNa2krS7qxNtdrtHAmzuYGFQLiQ13TsorsdT6ULTkPLKuu5+GsFpDlg6JFjUTwX2DyhMPG2be8uPrqsQ==}
+
+ webidl-conversions@8.0.1:
+ resolution: {integrity: sha512-BMhLD/Sw+GbJC21C/UgyaZX41nPt8bUTg+jWyDeg7e7YN4xOM05YPSIXceACnXVtqyEw/LMClUQMtMZ+PGGpqQ==}
+ engines: {node: '>=20'}
+
+ whatwg-encoding@3.1.1:
+ resolution: {integrity: sha512-6qN4hJdMwfYBtE3YBTTHhoeuUrDBPZmbQaxWAqSALV/MeEnR5z1xd8UKud2RAkFoPkmB+hli1TZSnyi84xz1vQ==}
+ engines: {node: '>=18'}
+ deprecated: Use @exodus/bytes instead for a more spec-conformant and faster implementation
+
+ whatwg-mimetype@4.0.0:
+ resolution: {integrity: sha512-QaKxh0eNIi2mE9p2vEdzfagOKHCcj1pJ56EEHGQOVxp8r9/iszLUUV7v89x9O1p/T+NlTM5W7jW6+cz4Fq1YVg==}
+ engines: {node: '>=18'}
+
+ whatwg-mimetype@5.0.0:
+ resolution: {integrity: sha512-sXcNcHOC51uPGF0P/D4NVtrkjSU2fNsm9iog4ZvZJsL3rjoDAzXZhkm2MWt1y+PUdggKAYVoMAIYcs78wJ51Cw==}
+ engines: {node: '>=20'}
+
+ whatwg-url@16.0.1:
+ resolution: {integrity: sha512-1to4zXBxmXHV3IiSSEInrreIlu02vUOvrhxJJH5vcxYTBDAx51cqZiKdyTxlecdKNSjj8EcxGBxNf6Vg+945gw==}
+ engines: {node: ^20.19.0 || ^22.12.0 || >=24.0.0}
+
+ which-pm-runs@1.1.0:
+ resolution: {integrity: sha512-n1brCuqClxfFfq/Rb0ICg9giSZqCS+pLtccdag6C2HyufBrh3fBOiy9nb6ggRMvWOVH5GrdJskj5iGTZNxd7SA==}
+ engines: {node: '>=4'}
+
+ why-is-node-running@2.3.0:
+ resolution: {integrity: sha512-hUrmaWBdVDcxvYqnyh09zunKzROWjbZTiNy8dBEjkS7ehEDQibXJ7XvlmtbwuTclUiIyN+CyXQD4Vmko8fNm8w==}
+ engines: {node: '>=8'}
+ hasBin: true
+
+ wrap-ansi@7.0.0:
+ resolution: {integrity: sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==}
+ engines: {node: '>=10'}
+
+ wrappy@1.0.2:
+ resolution: {integrity: sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==}
+
+ xml-name-validator@5.0.0:
+ resolution: {integrity: sha512-EvGK8EJ3DhaHfbRlETOWAS5pO9MZITeauHKJyb8wyajUfQUenkIg2MvLDTZ4T/TgIcm3HU0TFBgWWboAZ30UHg==}
+ engines: {node: '>=18'}
+
+ xml2js@0.5.0:
+ resolution: {integrity: sha512-drPFnkQJik/O+uPKpqSgr22mpuFHqKdbS835iAQrUC73L2F5WkboIRd63ai/2Yg6I1jzifPFKH2NTK+cfglkIA==}
+ engines: {node: '>=4.0.0'}
+
+ xmlbuilder@11.0.1:
+ resolution: {integrity: sha512-fDlsI/kFEx7gLvbecc0/ohLG50fugQp8ryHzMTuW9vSa1GJ0XYWKnhsUx7oie3G98+r56aTQIUB4kht42R3JvA==}
+ engines: {node: '>=4.0'}
+
+ xmlchars@2.2.0:
+ resolution: {integrity: sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw==}
+
+ xxhash-wasm@1.1.0:
+ resolution: {integrity: sha512-147y/6YNh+tlp6nd/2pWq38i9h6mz/EuQ6njIrmW8D1BS5nCqs0P6DG+m6zTGnNz5I+uhZ0SHxBs9BsPrwcKDA==}
+
+ y18n@5.0.8:
+ resolution: {integrity: sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==}
+ engines: {node: '>=10'}
+
+ yallist@5.0.0:
+ resolution: {integrity: sha512-YgvUTfwqyc7UXVMrB+SImsVYSmTS8X/tSrtdNZMImM+n7+QTriRXyXim0mBrTXNeqzVF0KWGgHPeiyViFFrNDw==}
+ engines: {node: '>=18'}
+
+ yaml-language-server@1.20.0:
+ resolution: {integrity: sha512-qhjK/bzSRZ6HtTvgeFvjNPJGWdZ0+x5NREV/9XZWFjIGezew2b4r5JPy66IfOhd5OA7KeFwk1JfmEbnTvev0cA==}
+ hasBin: true
+
+ yaml@2.7.1:
+ resolution: {integrity: sha512-10ULxpnOCQXxJvBgxsn9ptjq6uviG/htZKk9veJGhlqn3w/DxQ631zFF+nlQXLwmImeS5amR2dl2U8sg6U9jsQ==}
+ engines: {node: '>= 14'}
+ hasBin: true
+
+ yaml@2.8.3:
+ resolution: {integrity: sha512-AvbaCLOO2Otw/lW5bmh9d/WEdcDFdQp2Z2ZUH3pX9U2ihyUY0nvLv7J6TrWowklRGPYbB/IuIMfYgxaCPg5Bpg==}
+ engines: {node: '>= 14.6'}
+ hasBin: true
+
+ yargs-parser@21.1.1:
+ resolution: {integrity: sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==}
+ engines: {node: '>=12'}
+
+ yargs-parser@22.0.0:
+ resolution: {integrity: sha512-rwu/ClNdSMpkSrUb+d6BRsSkLUq1fmfsY6TOpYzTwvwkg1/NRG85KBy3kq++A8LKQwX6lsu+aWad+2khvuXrqw==}
+ engines: {node: ^20.19.0 || ^22.12.0 || >=23}
+
+ yargs@17.7.2:
+ resolution: {integrity: sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==}
+ engines: {node: '>=12'}
+
+ yauzl@2.10.0:
+ resolution: {integrity: sha512-p4a9I6X6nu6IhoGmBqAcbJy1mlC4j27vEPZX9F4L4/vZT3Lyq1VkFHw/V/PUcB9Buo+DG3iHkT0x3Qya58zc3g==}
+
+ yocto-queue@1.2.2:
+ resolution: {integrity: sha512-4LCcse/U2MHZ63HAJVE+v71o7yOdIe4cZ70Wpf8D/IyjDKYQLV5GD46B+hSTjJsvV5PztjvHoU580EftxjDZFQ==}
+ engines: {node: '>=12.20'}
+
+ zod@4.3.6:
+ resolution: {integrity: sha512-rftlrkhHZOcjDwkGlnUtZZkvaPHCsDATp4pGpuOOMDaTdDDXF91wuVDJoWoPsKX/3YPQ5fHuF3STjcYyKr+Qhg==}
+
+ zwitch@2.0.4:
+ resolution: {integrity: sha512-bXE4cR/kVZhKZX/RjPEflHaKVhUVl85noU3v6b8apfQEc1x4A+zBxjZ4lN8LqGd6WZ3dl98pY4o717VFmoPp+A==}
+
+snapshots:
+
+ '@adobe/css-tools@4.4.4': {}
+
+ '@antfu/install-pkg@1.1.0':
+ dependencies:
+ package-manager-detector: 1.6.0
+ tinyexec: 1.0.4
+
+ '@antfu/utils@8.1.1': {}
+
+ '@asamuzakjp/css-color@5.0.1':
+ dependencies:
+ '@csstools/css-calc': 3.1.1(@csstools/css-parser-algorithms@4.0.0(@csstools/css-tokenizer@4.0.0))(@csstools/css-tokenizer@4.0.0)
+ '@csstools/css-color-parser': 4.0.2(@csstools/css-parser-algorithms@4.0.0(@csstools/css-tokenizer@4.0.0))(@csstools/css-tokenizer@4.0.0)
+ '@csstools/css-parser-algorithms': 4.0.0(@csstools/css-tokenizer@4.0.0)
+ '@csstools/css-tokenizer': 4.0.0
+ lru-cache: 11.2.7
+
+ '@asamuzakjp/dom-selector@7.0.4':
+ dependencies:
+ '@asamuzakjp/nwsapi': 2.3.9
+ bidi-js: 1.0.3
+ css-tree: 3.2.1
+ is-potential-custom-element-name: 1.0.1
+ lru-cache: 11.2.7
+
+ '@asamuzakjp/nwsapi@2.3.9': {}
+
+ '@astrojs/check@0.9.8(prettier@3.8.1)(typescript@5.9.3)':
+ dependencies:
+ '@astrojs/language-server': 2.16.6(prettier@3.8.1)(typescript@5.9.3)
+ chokidar: 4.0.3
+ kleur: 4.1.5
+ typescript: 5.9.3
+ yargs: 17.7.2
+ transitivePeerDependencies:
+ - prettier
+ - prettier-plugin-astro
+
+ '@astrojs/compiler@2.13.1': {}
+
+ '@astrojs/compiler@3.0.1': {}
+
+ '@astrojs/internal-helpers@0.8.0':
+ dependencies:
+ picomatch: 4.0.3
+
+ '@astrojs/language-server@2.16.6(prettier@3.8.1)(typescript@5.9.3)':
+ dependencies:
+ '@astrojs/compiler': 2.13.1
+ '@astrojs/yaml2ts': 0.2.3
+ '@jridgewell/sourcemap-codec': 1.5.5
+ '@volar/kit': 2.4.28(typescript@5.9.3)
+ '@volar/language-core': 2.4.28
+ '@volar/language-server': 2.4.28
+ '@volar/language-service': 2.4.28
+ muggle-string: 0.4.1
+ tinyglobby: 0.2.15
+ volar-service-css: 0.0.70(@volar/language-service@2.4.28)
+ volar-service-emmet: 0.0.70(@volar/language-service@2.4.28)
+ volar-service-html: 0.0.70(@volar/language-service@2.4.28)
+ volar-service-prettier: 0.0.70(@volar/language-service@2.4.28)(prettier@3.8.1)
+ volar-service-typescript: 0.0.70(@volar/language-service@2.4.28)
+ volar-service-typescript-twoslash-queries: 0.0.70(@volar/language-service@2.4.28)
+ volar-service-yaml: 0.0.70(@volar/language-service@2.4.28)
+ vscode-html-languageservice: 5.6.2
+ vscode-uri: 3.1.0
+ optionalDependencies:
+ prettier: 3.8.1
+ transitivePeerDependencies:
+ - typescript
+
+ '@astrojs/markdown-remark@7.0.1':
+ dependencies:
+ '@astrojs/internal-helpers': 0.8.0
+ '@astrojs/prism': 4.0.1
+ github-slugger: 2.0.0
+ hast-util-from-html: 2.0.3
+ hast-util-to-text: 4.0.2
+ js-yaml: 4.1.1
+ mdast-util-definitions: 6.0.0
+ rehype-raw: 7.0.0
+ rehype-stringify: 10.0.1
+ remark-gfm: 4.0.1
+ remark-parse: 11.0.0
+ remark-rehype: 11.1.2
+ remark-smartypants: 3.0.2
+ shiki: 4.0.2
+ smol-toml: 1.6.1
+ unified: 11.0.5
+ unist-util-remove-position: 5.0.0
+ unist-util-visit: 5.1.0
+ unist-util-visit-parents: 6.0.2
+ vfile: 6.0.3
+ transitivePeerDependencies:
+ - supports-color
+
+ '@astrojs/prism@4.0.1':
+ dependencies:
+ prismjs: 1.30.0
+
+ '@astrojs/telemetry@3.3.0':
+ dependencies:
+ ci-info: 4.4.0
+ debug: 4.4.3
+ dlv: 1.1.3
+ dset: 3.1.4
+ is-docker: 3.0.0
+ is-wsl: 3.1.1
+ which-pm-runs: 1.1.0
+ transitivePeerDependencies:
+ - supports-color
+
+ '@astrojs/yaml2ts@0.2.3':
+ dependencies:
+ yaml: 2.8.3
+
+ '@babel/code-frame@7.29.0':
+ dependencies:
+ '@babel/helper-validator-identifier': 7.28.5
+ js-tokens: 4.0.0
+ picocolors: 1.1.1
+
+ '@babel/helper-string-parser@7.27.1': {}
+
+ '@babel/helper-validator-identifier@7.28.5': {}
+
+ '@babel/parser@7.29.2':
+ dependencies:
+ '@babel/types': 7.29.0
+
+ '@babel/types@7.29.0':
+ dependencies:
+ '@babel/helper-string-parser': 7.27.1
+ '@babel/helper-validator-identifier': 7.28.5
+
+ '@bcoe/v8-coverage@1.0.2': {}
+
+ '@bramus/specificity@2.4.2':
+ dependencies:
+ css-tree: 3.2.1
+
+ '@capsizecss/unpack@4.0.0':
+ dependencies:
+ fontkitten: 1.0.3
+
+ '@clack/core@1.1.0':
+ dependencies:
+ sisteransi: 1.0.5
+
+ '@clack/prompts@1.1.0':
+ dependencies:
+ '@clack/core': 1.1.0
+ sisteransi: 1.0.5
+
+ '@commitlint/cli@20.5.0(@types/node@25.5.0)(conventional-commits-parser@6.3.0)(typescript@5.9.3)':
+ dependencies:
+ '@commitlint/format': 20.5.0
+ '@commitlint/lint': 20.5.0
+ '@commitlint/load': 20.5.0(@types/node@25.5.0)(typescript@5.9.3)
+ '@commitlint/read': 20.5.0(conventional-commits-parser@6.3.0)
+ '@commitlint/types': 20.5.0
+ tinyexec: 1.0.4
+ yargs: 17.7.2
+ transitivePeerDependencies:
+ - '@types/node'
+ - conventional-commits-filter
+ - conventional-commits-parser
+ - typescript
+
+ '@commitlint/config-conventional@20.5.0':
+ dependencies:
+ '@commitlint/types': 20.5.0
+ conventional-changelog-conventionalcommits: 9.3.0
+
+ '@commitlint/config-validator@20.5.0':
+ dependencies:
+ '@commitlint/types': 20.5.0
+ ajv: 8.18.0
+
+ '@commitlint/ensure@20.5.0':
+ dependencies:
+ '@commitlint/types': 20.5.0
+ lodash.camelcase: 4.3.0
+ lodash.kebabcase: 4.1.1
+ lodash.snakecase: 4.1.1
+ lodash.startcase: 4.4.0
+ lodash.upperfirst: 4.3.1
+
+ '@commitlint/execute-rule@20.0.0': {}
+
+ '@commitlint/format@20.5.0':
+ dependencies:
+ '@commitlint/types': 20.5.0
+ picocolors: 1.1.1
+
+ '@commitlint/is-ignored@20.5.0':
+ dependencies:
+ '@commitlint/types': 20.5.0
+ semver: 7.7.4
+
+ '@commitlint/lint@20.5.0':
+ dependencies:
+ '@commitlint/is-ignored': 20.5.0
+ '@commitlint/parse': 20.5.0
+ '@commitlint/rules': 20.5.0
+ '@commitlint/types': 20.5.0
+
+ '@commitlint/load@20.5.0(@types/node@25.5.0)(typescript@5.9.3)':
+ dependencies:
+ '@commitlint/config-validator': 20.5.0
+ '@commitlint/execute-rule': 20.0.0
+ '@commitlint/resolve-extends': 20.5.0
+ '@commitlint/types': 20.5.0
+ cosmiconfig: 9.0.1(typescript@5.9.3)
+ cosmiconfig-typescript-loader: 6.2.0(@types/node@25.5.0)(cosmiconfig@9.0.1(typescript@5.9.3))(typescript@5.9.3)
+ is-plain-obj: 4.1.0
+ lodash.mergewith: 4.6.2
+ picocolors: 1.1.1
+ transitivePeerDependencies:
+ - '@types/node'
+ - typescript
+
+ '@commitlint/message@20.4.3': {}
+
+ '@commitlint/parse@20.5.0':
+ dependencies:
+ '@commitlint/types': 20.5.0
+ conventional-changelog-angular: 8.3.0
+ conventional-commits-parser: 6.3.0
+
+ '@commitlint/read@20.5.0(conventional-commits-parser@6.3.0)':
+ dependencies:
+ '@commitlint/top-level': 20.4.3
+ '@commitlint/types': 20.5.0
+ git-raw-commits: 5.0.1(conventional-commits-parser@6.3.0)
+ minimist: 1.2.8
+ tinyexec: 1.0.4
+ transitivePeerDependencies:
+ - conventional-commits-filter
+ - conventional-commits-parser
+
+ '@commitlint/resolve-extends@20.5.0':
+ dependencies:
+ '@commitlint/config-validator': 20.5.0
+ '@commitlint/types': 20.5.0
+ global-directory: 4.0.1
+ import-meta-resolve: 4.2.0
+ lodash.mergewith: 4.6.2
+ resolve-from: 5.0.0
+
+ '@commitlint/rules@20.5.0':
+ dependencies:
+ '@commitlint/ensure': 20.5.0
+ '@commitlint/message': 20.4.3
+ '@commitlint/to-lines': 20.0.0
+ '@commitlint/types': 20.5.0
+
+ '@commitlint/to-lines@20.0.0': {}
+
+ '@commitlint/top-level@20.4.3':
+ dependencies:
+ escalade: 3.2.0
+
+ '@commitlint/types@20.5.0':
+ dependencies:
+ conventional-commits-parser: 6.3.0
+ picocolors: 1.1.1
+
+ '@conventional-changelog/git-client@2.6.0(conventional-commits-parser@6.3.0)':
+ dependencies:
+ '@simple-libs/child-process-utils': 1.0.2
+ '@simple-libs/stream-utils': 1.2.0
+ semver: 7.7.4
+ optionalDependencies:
+ conventional-commits-parser: 6.3.0
+
+ '@csstools/color-helpers@6.0.2': {}
+
+ '@csstools/css-calc@3.1.1(@csstools/css-parser-algorithms@4.0.0(@csstools/css-tokenizer@4.0.0))(@csstools/css-tokenizer@4.0.0)':
+ dependencies:
+ '@csstools/css-parser-algorithms': 4.0.0(@csstools/css-tokenizer@4.0.0)
+ '@csstools/css-tokenizer': 4.0.0
+
+ '@csstools/css-color-parser@4.0.2(@csstools/css-parser-algorithms@4.0.0(@csstools/css-tokenizer@4.0.0))(@csstools/css-tokenizer@4.0.0)':
+ dependencies:
+ '@csstools/color-helpers': 6.0.2
+ '@csstools/css-calc': 3.1.1(@csstools/css-parser-algorithms@4.0.0(@csstools/css-tokenizer@4.0.0))(@csstools/css-tokenizer@4.0.0)
+ '@csstools/css-parser-algorithms': 4.0.0(@csstools/css-tokenizer@4.0.0)
+ '@csstools/css-tokenizer': 4.0.0
+
+ '@csstools/css-parser-algorithms@4.0.0(@csstools/css-tokenizer@4.0.0)':
+ dependencies:
+ '@csstools/css-tokenizer': 4.0.0
+
+ '@csstools/css-syntax-patches-for-csstree@1.1.1(css-tree@3.2.1)':
+ optionalDependencies:
+ css-tree: 3.2.1
+
+ '@csstools/css-tokenizer@4.0.0': {}
+
+ '@emmetio/abbreviation@2.3.3':
+ dependencies:
+ '@emmetio/scanner': 1.0.4
+
+ '@emmetio/css-abbreviation@2.1.8':
+ dependencies:
+ '@emmetio/scanner': 1.0.4
+
+ '@emmetio/css-parser@0.4.1':
+ dependencies:
+ '@emmetio/stream-reader': 2.2.0
+ '@emmetio/stream-reader-utils': 0.1.0
+
+ '@emmetio/html-matcher@1.3.0':
+ dependencies:
+ '@emmetio/scanner': 1.0.4
+
+ '@emmetio/scanner@1.0.4': {}
+
+ '@emmetio/stream-reader-utils@0.1.0': {}
+
+ '@emmetio/stream-reader@2.2.0': {}
+
+ '@emnapi/runtime@1.9.1':
+ dependencies:
+ tslib: 2.8.1
+ optional: true
+
+ '@esbuild/aix-ppc64@0.27.4':
+ optional: true
+
+ '@esbuild/android-arm64@0.27.4':
+ optional: true
+
+ '@esbuild/android-arm@0.27.4':
+ optional: true
+
+ '@esbuild/android-x64@0.27.4':
+ optional: true
+
+ '@esbuild/darwin-arm64@0.27.4':
+ optional: true
+
+ '@esbuild/darwin-x64@0.27.4':
+ optional: true
+
+ '@esbuild/freebsd-arm64@0.27.4':
+ optional: true
+
+ '@esbuild/freebsd-x64@0.27.4':
+ optional: true
+
+ '@esbuild/linux-arm64@0.27.4':
+ optional: true
+
+ '@esbuild/linux-arm@0.27.4':
+ optional: true
+
+ '@esbuild/linux-ia32@0.27.4':
+ optional: true
+
+ '@esbuild/linux-loong64@0.27.4':
+ optional: true
+
+ '@esbuild/linux-mips64el@0.27.4':
+ optional: true
+
+ '@esbuild/linux-ppc64@0.27.4':
+ optional: true
+
+ '@esbuild/linux-riscv64@0.27.4':
+ optional: true
+
+ '@esbuild/linux-s390x@0.27.4':
+ optional: true
+
+ '@esbuild/linux-x64@0.27.4':
+ optional: true
+
+ '@esbuild/netbsd-arm64@0.27.4':
+ optional: true
+
+ '@esbuild/netbsd-x64@0.27.4':
+ optional: true
+
+ '@esbuild/openbsd-arm64@0.27.4':
+ optional: true
+
+ '@esbuild/openbsd-x64@0.27.4':
+ optional: true
+
+ '@esbuild/openharmony-arm64@0.27.4':
+ optional: true
+
+ '@esbuild/sunos-x64@0.27.4':
+ optional: true
+
+ '@esbuild/win32-arm64@0.27.4':
+ optional: true
+
+ '@esbuild/win32-ia32@0.27.4':
+ optional: true
+
+ '@esbuild/win32-x64@0.27.4':
+ optional: true
+
+ '@exodus/bytes@1.15.0': {}
+
+ '@iconify-json/lucide@1.2.98':
+ dependencies:
+ '@iconify/types': 2.0.0
+
+ '@iconify/tools@4.2.0':
+ dependencies:
+ '@iconify/types': 2.0.0
+ '@iconify/utils': 2.3.0
+ cheerio: 1.2.0
+ domhandler: 5.0.3
+ extract-zip: 2.0.1
+ local-pkg: 1.1.2
+ pathe: 2.0.3
+ svgo: 3.3.3
+ tar: 7.5.13
+ transitivePeerDependencies:
+ - supports-color
+
+ '@iconify/types@2.0.0': {}
+
+ '@iconify/utils@2.3.0':
+ dependencies:
+ '@antfu/install-pkg': 1.1.0
+ '@antfu/utils': 8.1.1
+ '@iconify/types': 2.0.0
+ debug: 4.4.3
+ globals: 15.15.0
+ kolorist: 1.8.0
+ local-pkg: 1.1.2
+ mlly: 1.8.2
+ transitivePeerDependencies:
+ - supports-color
+
+ '@img/colour@1.1.0':
+ optional: true
+
+ '@img/sharp-darwin-arm64@0.34.5':
+ optionalDependencies:
+ '@img/sharp-libvips-darwin-arm64': 1.2.4
+ optional: true
+
+ '@img/sharp-darwin-x64@0.34.5':
+ optionalDependencies:
+ '@img/sharp-libvips-darwin-x64': 1.2.4
+ optional: true
+
+ '@img/sharp-libvips-darwin-arm64@1.2.4':
+ optional: true
+
+ '@img/sharp-libvips-darwin-x64@1.2.4':
+ optional: true
+
+ '@img/sharp-libvips-linux-arm64@1.2.4':
+ optional: true
+
+ '@img/sharp-libvips-linux-arm@1.2.4':
+ optional: true
+
+ '@img/sharp-libvips-linux-ppc64@1.2.4':
+ optional: true
+
+ '@img/sharp-libvips-linux-riscv64@1.2.4':
+ optional: true
+
+ '@img/sharp-libvips-linux-s390x@1.2.4':
+ optional: true
+
+ '@img/sharp-libvips-linux-x64@1.2.4':
+ optional: true
+
+ '@img/sharp-libvips-linuxmusl-arm64@1.2.4':
+ optional: true
+
+ '@img/sharp-libvips-linuxmusl-x64@1.2.4':
+ optional: true
+
+ '@img/sharp-linux-arm64@0.34.5':
+ optionalDependencies:
+ '@img/sharp-libvips-linux-arm64': 1.2.4
+ optional: true
+
+ '@img/sharp-linux-arm@0.34.5':
+ optionalDependencies:
+ '@img/sharp-libvips-linux-arm': 1.2.4
+ optional: true
+
+ '@img/sharp-linux-ppc64@0.34.5':
+ optionalDependencies:
+ '@img/sharp-libvips-linux-ppc64': 1.2.4
+ optional: true
+
+ '@img/sharp-linux-riscv64@0.34.5':
+ optionalDependencies:
+ '@img/sharp-libvips-linux-riscv64': 1.2.4
+ optional: true
+
+ '@img/sharp-linux-s390x@0.34.5':
+ optionalDependencies:
+ '@img/sharp-libvips-linux-s390x': 1.2.4
+ optional: true
+
+ '@img/sharp-linux-x64@0.34.5':
+ optionalDependencies:
+ '@img/sharp-libvips-linux-x64': 1.2.4
+ optional: true
+
+ '@img/sharp-linuxmusl-arm64@0.34.5':
+ optionalDependencies:
+ '@img/sharp-libvips-linuxmusl-arm64': 1.2.4
+ optional: true
+
+ '@img/sharp-linuxmusl-x64@0.34.5':
+ optionalDependencies:
+ '@img/sharp-libvips-linuxmusl-x64': 1.2.4
+ optional: true
+
+ '@img/sharp-wasm32@0.34.5':
+ dependencies:
+ '@emnapi/runtime': 1.9.1
+ optional: true
+
+ '@img/sharp-win32-arm64@0.34.5':
+ optional: true
+
+ '@img/sharp-win32-ia32@0.34.5':
+ optional: true
+
+ '@img/sharp-win32-x64@0.34.5':
+ optional: true
+
+ '@isaacs/fs-minipass@4.0.1':
+ dependencies:
+ minipass: 7.1.3
+
+ '@jridgewell/gen-mapping@0.3.13':
+ dependencies:
+ '@jridgewell/sourcemap-codec': 1.5.5
+ '@jridgewell/trace-mapping': 0.3.31
+
+ '@jridgewell/remapping@2.3.5':
+ dependencies:
+ '@jridgewell/gen-mapping': 0.3.13
+ '@jridgewell/trace-mapping': 0.3.31
+
+ '@jridgewell/resolve-uri@3.1.2': {}
+
+ '@jridgewell/sourcemap-codec@1.5.5': {}
+
+ '@jridgewell/trace-mapping@0.3.31':
+ dependencies:
+ '@jridgewell/resolve-uri': 3.1.2
+ '@jridgewell/sourcemap-codec': 1.5.5
+
+ '@oslojs/encoding@1.1.0': {}
+
+ '@oxfmt/binding-android-arm-eabi@0.41.0':
+ optional: true
+
+ '@oxfmt/binding-android-arm64@0.41.0':
+ optional: true
+
+ '@oxfmt/binding-darwin-arm64@0.41.0':
+ optional: true
+
+ '@oxfmt/binding-darwin-x64@0.41.0':
+ optional: true
+
+ '@oxfmt/binding-freebsd-x64@0.41.0':
+ optional: true
+
+ '@oxfmt/binding-linux-arm-gnueabihf@0.41.0':
+ optional: true
+
+ '@oxfmt/binding-linux-arm-musleabihf@0.41.0':
+ optional: true
+
+ '@oxfmt/binding-linux-arm64-gnu@0.41.0':
+ optional: true
+
+ '@oxfmt/binding-linux-arm64-musl@0.41.0':
+ optional: true
+
+ '@oxfmt/binding-linux-ppc64-gnu@0.41.0':
+ optional: true
+
+ '@oxfmt/binding-linux-riscv64-gnu@0.41.0':
+ optional: true
+
+ '@oxfmt/binding-linux-riscv64-musl@0.41.0':
+ optional: true
+
+ '@oxfmt/binding-linux-s390x-gnu@0.41.0':
+ optional: true
+
+ '@oxfmt/binding-linux-x64-gnu@0.41.0':
+ optional: true
+
+ '@oxfmt/binding-linux-x64-musl@0.41.0':
+ optional: true
+
+ '@oxfmt/binding-openharmony-arm64@0.41.0':
+ optional: true
+
+ '@oxfmt/binding-win32-arm64-msvc@0.41.0':
+ optional: true
+
+ '@oxfmt/binding-win32-ia32-msvc@0.41.0':
+ optional: true
+
+ '@oxfmt/binding-win32-x64-msvc@0.41.0':
+ optional: true
+
+ '@oxlint/binding-android-arm-eabi@1.56.0':
+ optional: true
+
+ '@oxlint/binding-android-arm64@1.56.0':
+ optional: true
+
+ '@oxlint/binding-darwin-arm64@1.56.0':
+ optional: true
+
+ '@oxlint/binding-darwin-x64@1.56.0':
+ optional: true
+
+ '@oxlint/binding-freebsd-x64@1.56.0':
+ optional: true
+
+ '@oxlint/binding-linux-arm-gnueabihf@1.56.0':
+ optional: true
+
+ '@oxlint/binding-linux-arm-musleabihf@1.56.0':
+ optional: true
+
+ '@oxlint/binding-linux-arm64-gnu@1.56.0':
+ optional: true
+
+ '@oxlint/binding-linux-arm64-musl@1.56.0':
+ optional: true
+
+ '@oxlint/binding-linux-ppc64-gnu@1.56.0':
+ optional: true
+
+ '@oxlint/binding-linux-riscv64-gnu@1.56.0':
+ optional: true
+
+ '@oxlint/binding-linux-riscv64-musl@1.56.0':
+ optional: true
+
+ '@oxlint/binding-linux-s390x-gnu@1.56.0':
+ optional: true
+
+ '@oxlint/binding-linux-x64-gnu@1.56.0':
+ optional: true
+
+ '@oxlint/binding-linux-x64-musl@1.56.0':
+ optional: true
+
+ '@oxlint/binding-openharmony-arm64@1.56.0':
+ optional: true
+
+ '@oxlint/binding-win32-arm64-msvc@1.56.0':
+ optional: true
+
+ '@oxlint/binding-win32-ia32-msvc@1.56.0':
+ optional: true
+
+ '@oxlint/binding-win32-x64-msvc@1.56.0':
+ optional: true
+
+ '@playwright/test@1.58.2':
+ dependencies:
+ playwright: 1.58.2
+
+ '@polka/url@1.0.0-next.29': {}
+
+ '@rollup/pluginutils@5.3.0(rollup@4.60.0)':
+ dependencies:
+ '@types/estree': 1.0.8
+ estree-walker: 2.0.2
+ picomatch: 4.0.3
+ optionalDependencies:
+ rollup: 4.60.0
+
+ '@rollup/rollup-android-arm-eabi@4.60.0':
+ optional: true
+
+ '@rollup/rollup-android-arm64@4.60.0':
+ optional: true
+
+ '@rollup/rollup-darwin-arm64@4.60.0':
+ optional: true
+
+ '@rollup/rollup-darwin-x64@4.60.0':
+ optional: true
+
+ '@rollup/rollup-freebsd-arm64@4.60.0':
+ optional: true
+
+ '@rollup/rollup-freebsd-x64@4.60.0':
+ optional: true
+
+ '@rollup/rollup-linux-arm-gnueabihf@4.60.0':
+ optional: true
+
+ '@rollup/rollup-linux-arm-musleabihf@4.60.0':
+ optional: true
+
+ '@rollup/rollup-linux-arm64-gnu@4.60.0':
+ optional: true
+
+ '@rollup/rollup-linux-arm64-musl@4.60.0':
+ optional: true
+
+ '@rollup/rollup-linux-loong64-gnu@4.60.0':
+ optional: true
+
+ '@rollup/rollup-linux-loong64-musl@4.60.0':
+ optional: true
+
+ '@rollup/rollup-linux-ppc64-gnu@4.60.0':
+ optional: true
+
+ '@rollup/rollup-linux-ppc64-musl@4.60.0':
+ optional: true
+
+ '@rollup/rollup-linux-riscv64-gnu@4.60.0':
+ optional: true
+
+ '@rollup/rollup-linux-riscv64-musl@4.60.0':
+ optional: true
+
+ '@rollup/rollup-linux-s390x-gnu@4.60.0':
+ optional: true
+
+ '@rollup/rollup-linux-x64-gnu@4.60.0':
+ optional: true
+
+ '@rollup/rollup-linux-x64-musl@4.60.0':
+ optional: true
+
+ '@rollup/rollup-openbsd-x64@4.60.0':
+ optional: true
+
+ '@rollup/rollup-openharmony-arm64@4.60.0':
+ optional: true
+
+ '@rollup/rollup-win32-arm64-msvc@4.60.0':
+ optional: true
+
+ '@rollup/rollup-win32-ia32-msvc@4.60.0':
+ optional: true
+
+ '@rollup/rollup-win32-x64-gnu@4.60.0':
+ optional: true
+
+ '@rollup/rollup-win32-x64-msvc@4.60.0':
+ optional: true
+
+ '@shikijs/core@4.0.2':
+ dependencies:
+ '@shikijs/primitive': 4.0.2
+ '@shikijs/types': 4.0.2
+ '@shikijs/vscode-textmate': 10.0.2
+ '@types/hast': 3.0.4
+ hast-util-to-html: 9.0.5
+
+ '@shikijs/engine-javascript@4.0.2':
+ dependencies:
+ '@shikijs/types': 4.0.2
+ '@shikijs/vscode-textmate': 10.0.2
+ oniguruma-to-es: 4.3.5
+
+ '@shikijs/engine-oniguruma@4.0.2':
+ dependencies:
+ '@shikijs/types': 4.0.2
+ '@shikijs/vscode-textmate': 10.0.2
+
+ '@shikijs/langs@4.0.2':
+ dependencies:
+ '@shikijs/types': 4.0.2
+
+ '@shikijs/primitive@4.0.2':
+ dependencies:
+ '@shikijs/types': 4.0.2
+ '@shikijs/vscode-textmate': 10.0.2
+ '@types/hast': 3.0.4
+
+ '@shikijs/themes@4.0.2':
+ dependencies:
+ '@shikijs/types': 4.0.2
+
+ '@shikijs/types@4.0.2':
+ dependencies:
+ '@shikijs/vscode-textmate': 10.0.2
+ '@types/hast': 3.0.4
+
+ '@shikijs/vscode-textmate@10.0.2': {}
+
+ '@simple-libs/child-process-utils@1.0.2':
+ dependencies:
+ '@simple-libs/stream-utils': 1.2.0
+
+ '@simple-libs/stream-utils@1.2.0': {}
+
+ '@standard-schema/spec@1.1.0': {}
+
+ '@tailwindcss/node@4.2.2':
+ dependencies:
+ '@jridgewell/remapping': 2.3.5
+ enhanced-resolve: 5.20.1
+ jiti: 2.6.1
+ lightningcss: 1.32.0
+ magic-string: 0.30.21
+ source-map-js: 1.2.1
+ tailwindcss: 4.2.2
+
+ '@tailwindcss/oxide-android-arm64@4.2.2':
+ optional: true
+
+ '@tailwindcss/oxide-darwin-arm64@4.2.2':
+ optional: true
+
+ '@tailwindcss/oxide-darwin-x64@4.2.2':
+ optional: true
+
+ '@tailwindcss/oxide-freebsd-x64@4.2.2':
+ optional: true
+
+ '@tailwindcss/oxide-linux-arm-gnueabihf@4.2.2':
+ optional: true
+
+ '@tailwindcss/oxide-linux-arm64-gnu@4.2.2':
+ optional: true
+
+ '@tailwindcss/oxide-linux-arm64-musl@4.2.2':
+ optional: true
+
+ '@tailwindcss/oxide-linux-x64-gnu@4.2.2':
+ optional: true
+
+ '@tailwindcss/oxide-linux-x64-musl@4.2.2':
+ optional: true
+
+ '@tailwindcss/oxide-wasm32-wasi@4.2.2':
+ optional: true
+
+ '@tailwindcss/oxide-win32-arm64-msvc@4.2.2':
+ optional: true
+
+ '@tailwindcss/oxide-win32-x64-msvc@4.2.2':
+ optional: true
+
+ '@tailwindcss/oxide@4.2.2':
+ optionalDependencies:
+ '@tailwindcss/oxide-android-arm64': 4.2.2
+ '@tailwindcss/oxide-darwin-arm64': 4.2.2
+ '@tailwindcss/oxide-darwin-x64': 4.2.2
+ '@tailwindcss/oxide-freebsd-x64': 4.2.2
+ '@tailwindcss/oxide-linux-arm-gnueabihf': 4.2.2
+ '@tailwindcss/oxide-linux-arm64-gnu': 4.2.2
+ '@tailwindcss/oxide-linux-arm64-musl': 4.2.2
+ '@tailwindcss/oxide-linux-x64-gnu': 4.2.2
+ '@tailwindcss/oxide-linux-x64-musl': 4.2.2
+ '@tailwindcss/oxide-wasm32-wasi': 4.2.2
+ '@tailwindcss/oxide-win32-arm64-msvc': 4.2.2
+ '@tailwindcss/oxide-win32-x64-msvc': 4.2.2
+
+ '@tailwindcss/vite@4.2.2(vite@7.3.1(@types/node@25.5.0)(jiti@2.6.1)(lightningcss@1.32.0)(yaml@2.8.3))':
+ dependencies:
+ '@tailwindcss/node': 4.2.2
+ '@tailwindcss/oxide': 4.2.2
+ tailwindcss: 4.2.2
+ vite: 7.3.1(@types/node@25.5.0)(jiti@2.6.1)(lightningcss@1.32.0)(yaml@2.8.3)
+
+ '@testing-library/jest-dom@6.9.1':
+ dependencies:
+ '@adobe/css-tools': 4.4.4
+ aria-query: 5.3.2
+ css.escape: 1.5.1
+ dom-accessibility-api: 0.6.3
+ picocolors: 1.1.1
+ redent: 3.0.0
+
+ '@types/chai@5.2.3':
+ dependencies:
+ '@types/deep-eql': 4.0.2
+ assertion-error: 2.0.1
+
+ '@types/concat-stream@1.6.1':
+ dependencies:
+ '@types/node': 25.5.0
+
+ '@types/debug@4.1.13':
+ dependencies:
+ '@types/ms': 2.1.0
+
+ '@types/deep-eql@4.0.2': {}
+
+ '@types/estree@1.0.8': {}
+
+ '@types/form-data@0.0.33':
+ dependencies:
+ '@types/node': 25.5.0
+
+ '@types/hast@3.0.4':
+ dependencies:
+ '@types/unist': 3.0.3
+
+ '@types/mdast@4.0.4':
+ dependencies:
+ '@types/unist': 3.0.3
+
+ '@types/ms@2.1.0': {}
+
+ '@types/nlcst@2.0.3':
+ dependencies:
+ '@types/unist': 3.0.3
+
+ '@types/node@10.17.60': {}
+
+ '@types/node@25.5.0':
+ dependencies:
+ undici-types: 7.18.2
+
+ '@types/node@8.10.66': {}
+
+ '@types/qs@6.15.0': {}
+
+ '@types/unist@3.0.3': {}
+
+ '@types/yauzl@2.10.3':
+ dependencies:
+ '@types/node': 25.5.0
+ optional: true
+
+ '@ungap/structured-clone@1.3.0': {}
+
+ '@vitest/coverage-v8@4.1.1(vitest@4.1.1)':
+ dependencies:
+ '@bcoe/v8-coverage': 1.0.2
+ '@vitest/utils': 4.1.1
+ ast-v8-to-istanbul: 1.0.0
+ istanbul-lib-coverage: 3.2.2
+ istanbul-lib-report: 3.0.1
+ istanbul-reports: 3.2.0
+ magicast: 0.5.2
+ obug: 2.1.1
+ std-env: 4.0.0
+ tinyrainbow: 3.1.0
+ vitest: 4.1.1(@types/node@25.5.0)(@vitest/ui@4.1.1)(jsdom@29.0.1)(vite@7.3.1(@types/node@25.5.0)(jiti@2.6.1)(lightningcss@1.32.0)(yaml@2.8.3))
+
+ '@vitest/expect@4.1.1':
+ dependencies:
+ '@standard-schema/spec': 1.1.0
+ '@types/chai': 5.2.3
+ '@vitest/spy': 4.1.1
+ '@vitest/utils': 4.1.1
+ chai: 6.2.2
+ tinyrainbow: 3.1.0
+
+ '@vitest/mocker@4.1.1(vite@7.3.1(@types/node@25.5.0)(jiti@2.6.1)(lightningcss@1.32.0)(yaml@2.8.3))':
+ dependencies:
+ '@vitest/spy': 4.1.1
+ estree-walker: 3.0.3
+ magic-string: 0.30.21
+ optionalDependencies:
+ vite: 7.3.1(@types/node@25.5.0)(jiti@2.6.1)(lightningcss@1.32.0)(yaml@2.8.3)
+
+ '@vitest/pretty-format@4.1.1':
+ dependencies:
+ tinyrainbow: 3.1.0
+
+ '@vitest/runner@4.1.1':
+ dependencies:
+ '@vitest/utils': 4.1.1
+ pathe: 2.0.3
+
+ '@vitest/snapshot@4.1.1':
+ dependencies:
+ '@vitest/pretty-format': 4.1.1
+ '@vitest/utils': 4.1.1
+ magic-string: 0.30.21
+ pathe: 2.0.3
+
+ '@vitest/spy@4.1.1': {}
+
+ '@vitest/ui@4.1.1(vitest@4.1.1)':
+ dependencies:
+ '@vitest/utils': 4.1.1
+ fflate: 0.8.2
+ flatted: 3.4.0
+ pathe: 2.0.3
+ sirv: 3.0.2
+ tinyglobby: 0.2.15
+ tinyrainbow: 3.1.0
+ vitest: 4.1.1(@types/node@25.5.0)(@vitest/ui@4.1.1)(jsdom@29.0.1)(vite@7.3.1(@types/node@25.5.0)(jiti@2.6.1)(lightningcss@1.32.0)(yaml@2.8.3))
+
+ '@vitest/utils@4.1.1':
+ dependencies:
+ '@vitest/pretty-format': 4.1.1
+ convert-source-map: 2.0.0
+ tinyrainbow: 3.1.0
+
+ '@volar/kit@2.4.28(typescript@5.9.3)':
+ dependencies:
+ '@volar/language-service': 2.4.28
+ '@volar/typescript': 2.4.28
+ typesafe-path: 0.2.2
+ typescript: 5.9.3
+ vscode-languageserver-textdocument: 1.0.12
+ vscode-uri: 3.1.0
+
+ '@volar/language-core@2.4.28':
+ dependencies:
+ '@volar/source-map': 2.4.28
+
+ '@volar/language-server@2.4.28':
+ dependencies:
+ '@volar/language-core': 2.4.28
+ '@volar/language-service': 2.4.28
+ '@volar/typescript': 2.4.28
+ path-browserify: 1.0.1
+ request-light: 0.7.0
+ vscode-languageserver: 9.0.1
+ vscode-languageserver-protocol: 3.17.5
+ vscode-languageserver-textdocument: 1.0.12
+ vscode-uri: 3.1.0
+
+ '@volar/language-service@2.4.28':
+ dependencies:
+ '@volar/language-core': 2.4.28
+ vscode-languageserver-protocol: 3.17.5
+ vscode-languageserver-textdocument: 1.0.12
+ vscode-uri: 3.1.0
+
+ '@volar/source-map@2.4.28': {}
+
+ '@volar/typescript@2.4.28':
+ dependencies:
+ '@volar/language-core': 2.4.28
+ path-browserify: 1.0.1
+ vscode-uri: 3.1.0
+
+ '@vscode/emmet-helper@2.11.0':
+ dependencies:
+ emmet: 2.4.11
+ jsonc-parser: 2.3.1
+ vscode-languageserver-textdocument: 1.0.12
+ vscode-languageserver-types: 3.17.5
+ vscode-uri: 3.1.0
+
+ '@vscode/l10n@0.0.18': {}
+
+ acorn@8.16.0: {}
+
+ ajv-draft-04@1.0.0(ajv@8.18.0):
+ optionalDependencies:
+ ajv: 8.18.0
+
+ ajv@8.18.0:
+ dependencies:
+ fast-deep-equal: 3.1.3
+ fast-uri: 3.1.0
+ json-schema-traverse: 1.0.0
+ require-from-string: 2.0.2
+
+ ansi-regex@5.0.1: {}
+
+ ansi-styles@4.3.0:
+ dependencies:
+ color-convert: 2.0.1
+
+ anymatch@3.1.3:
+ dependencies:
+ normalize-path: 3.0.0
+ picomatch: 2.3.1
+
+ argparse@2.0.1: {}
+
+ aria-query@5.3.2: {}
+
+ array-ify@1.0.0: {}
+
+ array-iterate@2.0.1: {}
+
+ asap@2.0.6: {}
+
+ assertion-error@2.0.1: {}
+
+ ast-v8-to-istanbul@1.0.0:
+ dependencies:
+ '@jridgewell/trace-mapping': 0.3.31
+ estree-walker: 3.0.3
+ js-tokens: 10.0.0
+
+ astro-icon@1.1.5:
+ dependencies:
+ '@iconify/tools': 4.2.0
+ '@iconify/types': 2.0.0
+ '@iconify/utils': 2.3.0
+ transitivePeerDependencies:
+ - supports-color
+
+ astro@6.0.8(@types/node@25.5.0)(jiti@2.6.1)(lightningcss@1.32.0)(rollup@4.60.0)(typescript@5.9.3)(yaml@2.8.3):
+ dependencies:
+ '@astrojs/compiler': 3.0.1
+ '@astrojs/internal-helpers': 0.8.0
+ '@astrojs/markdown-remark': 7.0.1
+ '@astrojs/telemetry': 3.3.0
+ '@capsizecss/unpack': 4.0.0
+ '@clack/prompts': 1.1.0
+ '@oslojs/encoding': 1.1.0
+ '@rollup/pluginutils': 5.3.0(rollup@4.60.0)
+ aria-query: 5.3.2
+ axobject-query: 4.1.0
+ ci-info: 4.4.0
+ clsx: 2.1.1
+ common-ancestor-path: 2.0.0
+ cookie: 1.1.1
+ devalue: 5.6.4
+ diff: 8.0.4
+ dlv: 1.1.3
+ dset: 3.1.4
+ es-module-lexer: 2.0.0
+ esbuild: 0.27.4
+ flattie: 1.1.1
+ fontace: 0.4.1
+ github-slugger: 2.0.0
+ html-escaper: 3.0.3
+ http-cache-semantics: 4.2.0
+ js-yaml: 4.1.1
+ magic-string: 0.30.21
+ magicast: 0.5.2
+ mrmime: 2.0.1
+ neotraverse: 0.6.18
+ obug: 2.1.1
+ p-limit: 7.3.0
+ p-queue: 9.1.0
+ package-manager-detector: 1.6.0
+ piccolore: 0.1.3
+ picomatch: 4.0.3
+ rehype: 13.0.2
+ semver: 7.7.4
+ shiki: 4.0.2
+ smol-toml: 1.6.1
+ svgo: 4.0.1
+ tinyclip: 0.1.12
+ tinyexec: 1.0.4
+ tinyglobby: 0.2.15
+ tsconfck: 3.1.6(typescript@5.9.3)
+ ultrahtml: 1.6.0
+ unifont: 0.7.4
+ unist-util-visit: 5.1.0
+ unstorage: 1.17.4
+ vfile: 6.0.3
+ vite: 7.3.1(@types/node@25.5.0)(jiti@2.6.1)(lightningcss@1.32.0)(yaml@2.8.3)
+ vitefu: 1.1.2(vite@7.3.1(@types/node@25.5.0)(jiti@2.6.1)(lightningcss@1.32.0)(yaml@2.8.3))
+ xxhash-wasm: 1.1.0
+ yargs-parser: 22.0.0
+ zod: 4.3.6
+ optionalDependencies:
+ sharp: 0.34.5
+ transitivePeerDependencies:
+ - '@azure/app-configuration'
+ - '@azure/cosmos'
+ - '@azure/data-tables'
+ - '@azure/identity'
+ - '@azure/keyvault-secrets'
+ - '@azure/storage-blob'
+ - '@capacitor/preferences'
+ - '@deno/kv'
+ - '@netlify/blobs'
+ - '@planetscale/database'
+ - '@types/node'
+ - '@upstash/redis'
+ - '@vercel/blob'
+ - '@vercel/functions'
+ - '@vercel/kv'
+ - aws4fetch
+ - db0
+ - idb-keyval
+ - ioredis
+ - jiti
+ - less
+ - lightningcss
+ - rollup
+ - sass
+ - sass-embedded
+ - stylus
+ - sugarss
+ - supports-color
+ - terser
+ - tsx
+ - typescript
+ - uploadthing
+ - yaml
+
+ asynckit@0.4.0: {}
+
+ autoprefixer@10.4.27(postcss@8.5.8):
+ dependencies:
+ browserslist: 4.28.1
+ caniuse-lite: 1.0.30001781
+ fraction.js: 5.3.4
+ picocolors: 1.1.1
+ postcss: 8.5.8
+ postcss-value-parser: 4.2.0
+
+ axobject-query@4.1.0: {}
+
+ bail@2.0.2: {}
+
+ baseline-browser-mapping@2.10.10: {}
+
+ bidi-js@1.0.3:
+ dependencies:
+ require-from-string: 2.0.2
+
+ boolbase@1.0.0: {}
+
+ browserslist@4.28.1:
+ dependencies:
+ baseline-browser-mapping: 2.10.10
+ caniuse-lite: 1.0.30001781
+ electron-to-chromium: 1.5.321
+ node-releases: 2.0.36
+ update-browserslist-db: 1.2.3(browserslist@4.28.1)
+
+ buffer-crc32@0.2.13: {}
+
+ buffer-from@1.1.2: {}
+
+ call-bind-apply-helpers@1.0.2:
+ dependencies:
+ es-errors: 1.3.0
+ function-bind: 1.1.2
+
+ call-bound@1.0.4:
+ dependencies:
+ call-bind-apply-helpers: 1.0.2
+ get-intrinsic: 1.3.0
+
+ callsites@3.1.0: {}
+
+ caniuse-lite@1.0.30001781: {}
+
+ caseless@0.12.0: {}
+
+ ccount@2.0.1: {}
+
+ chai@6.2.2: {}
+
+ character-entities-html4@2.1.0: {}
+
+ character-entities-legacy@3.0.0: {}
+
+ character-entities@2.0.2: {}
+
+ cheerio-select@2.1.0:
+ dependencies:
+ boolbase: 1.0.0
+ css-select: 5.2.2
+ css-what: 6.2.2
+ domelementtype: 2.3.0
+ domhandler: 5.0.3
+ domutils: 3.2.2
+
+ cheerio@1.2.0:
+ dependencies:
+ cheerio-select: 2.1.0
+ dom-serializer: 2.0.0
+ domhandler: 5.0.3
+ domutils: 3.2.2
+ encoding-sniffer: 0.2.1
+ htmlparser2: 10.1.0
+ parse5: 7.3.0
+ parse5-htmlparser2-tree-adapter: 7.1.0
+ parse5-parser-stream: 7.1.2
+ undici: 7.24.5
+ whatwg-mimetype: 4.0.0
+
+ chokidar@4.0.3:
+ dependencies:
+ readdirp: 4.1.2
+
+ chokidar@5.0.0:
+ dependencies:
+ readdirp: 5.0.0
+
+ chownr@3.0.0: {}
+
+ ci-info@4.4.0: {}
+
+ cliui@8.0.1:
+ dependencies:
+ string-width: 4.2.3
+ strip-ansi: 6.0.1
+ wrap-ansi: 7.0.0
+
+ clsx@2.1.1: {}
+
+ color-convert@2.0.1:
+ dependencies:
+ color-name: 1.1.4
+
+ color-name@1.1.4: {}
+
+ combined-stream@1.0.8:
+ dependencies:
+ delayed-stream: 1.0.0
+
+ comma-separated-tokens@2.0.3: {}
+
+ commander@11.1.0: {}
+
+ commander@7.2.0: {}
+
+ common-ancestor-path@2.0.0: {}
+
+ compare-func@2.0.0:
+ dependencies:
+ array-ify: 1.0.0
+ dot-prop: 5.3.0
+
+ concat-stream@1.6.2:
+ dependencies:
+ buffer-from: 1.1.2
+ inherits: 2.0.4
+ readable-stream: 2.3.8
+ typedarray: 0.0.6
+
+ confbox@0.1.8: {}
+
+ confbox@0.2.4: {}
+
+ conventional-changelog-angular@8.3.0:
+ dependencies:
+ compare-func: 2.0.0
+
+ conventional-changelog-conventionalcommits@9.3.0:
+ dependencies:
+ compare-func: 2.0.0
+
+ conventional-commits-parser@6.3.0:
+ dependencies:
+ '@simple-libs/stream-utils': 1.2.0
+ meow: 13.2.0
+
+ convert-source-map@2.0.0: {}
+
+ cookie-es@1.2.2: {}
+
+ cookie@1.1.1: {}
+
+ core-util-is@1.0.3: {}
+
+ cosmiconfig-typescript-loader@6.2.0(@types/node@25.5.0)(cosmiconfig@9.0.1(typescript@5.9.3))(typescript@5.9.3):
+ dependencies:
+ '@types/node': 25.5.0
+ cosmiconfig: 9.0.1(typescript@5.9.3)
+ jiti: 2.6.1
+ typescript: 5.9.3
+
+ cosmiconfig@9.0.1(typescript@5.9.3):
+ dependencies:
+ env-paths: 2.2.1
+ import-fresh: 3.3.1
+ js-yaml: 4.1.1
+ parse-json: 5.2.0
+ optionalDependencies:
+ typescript: 5.9.3
+
+ crossws@0.3.5:
+ dependencies:
+ uncrypto: 0.1.3
+
+ css-select@5.2.2:
+ dependencies:
+ boolbase: 1.0.0
+ css-what: 6.2.2
+ domhandler: 5.0.3
+ domutils: 3.2.2
+ nth-check: 2.1.1
+
+ css-tree@2.2.1:
+ dependencies:
+ mdn-data: 2.0.28
+ source-map-js: 1.2.1
+
+ css-tree@2.3.1:
+ dependencies:
+ mdn-data: 2.0.30
+ source-map-js: 1.2.1
+
+ css-tree@3.2.1:
+ dependencies:
+ mdn-data: 2.27.1
+ source-map-js: 1.2.1
+
+ css-what@6.2.2: {}
+
+ css.escape@1.5.1: {}
+
+ csso@5.0.5:
+ dependencies:
+ css-tree: 2.2.1
+
+ data-urls@7.0.0:
+ dependencies:
+ whatwg-mimetype: 5.0.0
+ whatwg-url: 16.0.1
+ transitivePeerDependencies:
+ - '@noble/hashes'
+
+ debug@4.4.3:
+ dependencies:
+ ms: 2.1.3
+
+ decimal.js@10.6.0: {}
+
+ decode-named-character-reference@1.3.0:
+ dependencies:
+ character-entities: 2.0.2
+
+ defu@6.1.4: {}
+
+ delayed-stream@1.0.0: {}
+
+ dequal@2.0.3: {}
+
+ destr@2.0.5: {}
+
+ detect-libc@2.1.2: {}
+
+ devalue@5.6.4: {}
+
+ devlop@1.1.0:
+ dependencies:
+ dequal: 2.0.3
+
+ diff@8.0.4: {}
+
+ dlv@1.1.3: {}
+
+ dom-accessibility-api@0.6.3: {}
+
+ dom-serializer@2.0.0:
+ dependencies:
+ domelementtype: 2.3.0
+ domhandler: 5.0.3
+ entities: 4.5.0
+
+ domelementtype@2.3.0: {}
+
+ domhandler@5.0.3:
+ dependencies:
+ domelementtype: 2.3.0
+
+ domutils@3.2.2:
+ dependencies:
+ dom-serializer: 2.0.0
+ domelementtype: 2.3.0
+ domhandler: 5.0.3
+
+ dot-prop@5.3.0:
+ dependencies:
+ is-obj: 2.0.0
+
+ dset@3.1.4: {}
+
+ dunder-proto@1.0.1:
+ dependencies:
+ call-bind-apply-helpers: 1.0.2
+ es-errors: 1.3.0
+ gopd: 1.2.0
+
+ electron-to-chromium@1.5.321: {}
+
+ emmet@2.4.11:
+ dependencies:
+ '@emmetio/abbreviation': 2.3.3
+ '@emmetio/css-abbreviation': 2.1.8
+
+ emoji-regex@8.0.0: {}
+
+ encoding-sniffer@0.2.1:
+ dependencies:
+ iconv-lite: 0.6.3
+ whatwg-encoding: 3.1.1
+
+ end-of-stream@1.4.5:
+ dependencies:
+ once: 1.4.0
+
+ enhanced-resolve@5.20.1:
+ dependencies:
+ graceful-fs: 4.2.11
+ tapable: 2.3.1
+
+ entities@2.2.0: {}
+
+ entities@4.5.0: {}
+
+ entities@6.0.1: {}
+
+ entities@7.0.1: {}
+
+ env-paths@2.2.1: {}
+
+ error-ex@1.3.4:
+ dependencies:
+ is-arrayish: 0.2.1
+
+ es-define-property@1.0.1: {}
+
+ es-errors@1.3.0: {}
+
+ es-module-lexer@2.0.0: {}
+
+ es-object-atoms@1.1.1:
+ dependencies:
+ es-errors: 1.3.0
+
+ es-set-tostringtag@2.1.0:
+ dependencies:
+ es-errors: 1.3.0
+ get-intrinsic: 1.3.0
+ has-tostringtag: 1.0.2
+ hasown: 2.0.2
+
+ esbuild@0.27.4:
+ optionalDependencies:
+ '@esbuild/aix-ppc64': 0.27.4
+ '@esbuild/android-arm': 0.27.4
+ '@esbuild/android-arm64': 0.27.4
+ '@esbuild/android-x64': 0.27.4
+ '@esbuild/darwin-arm64': 0.27.4
+ '@esbuild/darwin-x64': 0.27.4
+ '@esbuild/freebsd-arm64': 0.27.4
+ '@esbuild/freebsd-x64': 0.27.4
+ '@esbuild/linux-arm': 0.27.4
+ '@esbuild/linux-arm64': 0.27.4
+ '@esbuild/linux-ia32': 0.27.4
+ '@esbuild/linux-loong64': 0.27.4
+ '@esbuild/linux-mips64el': 0.27.4
+ '@esbuild/linux-ppc64': 0.27.4
+ '@esbuild/linux-riscv64': 0.27.4
+ '@esbuild/linux-s390x': 0.27.4
+ '@esbuild/linux-x64': 0.27.4
+ '@esbuild/netbsd-arm64': 0.27.4
+ '@esbuild/netbsd-x64': 0.27.4
+ '@esbuild/openbsd-arm64': 0.27.4
+ '@esbuild/openbsd-x64': 0.27.4
+ '@esbuild/openharmony-arm64': 0.27.4
+ '@esbuild/sunos-x64': 0.27.4
+ '@esbuild/win32-arm64': 0.27.4
+ '@esbuild/win32-ia32': 0.27.4
+ '@esbuild/win32-x64': 0.27.4
+
+ escalade@3.2.0: {}
+
+ escape-string-regexp@5.0.0: {}
+
+ estree-walker@2.0.2: {}
+
+ estree-walker@3.0.3:
+ dependencies:
+ '@types/estree': 1.0.8
+
+ eventemitter3@5.0.4: {}
+
+ expect-type@1.3.0: {}
+
+ exsolve@1.0.8: {}
+
+ extend@3.0.2: {}
+
+ extract-zip@2.0.1:
+ dependencies:
+ debug: 4.4.3
+ get-stream: 5.2.0
+ yauzl: 2.10.0
+ optionalDependencies:
+ '@types/yauzl': 2.10.3
+ transitivePeerDependencies:
+ - supports-color
+
+ fast-deep-equal@3.1.3: {}
+
+ fast-uri@3.1.0: {}
+
+ fd-slicer@1.1.0:
+ dependencies:
+ pend: 1.2.0
+
+ fdir@6.5.0(picomatch@4.0.3):
+ optionalDependencies:
+ picomatch: 4.0.3
+
+ fflate@0.8.2: {}
+
+ flatted@3.4.0: {}
+
+ flattie@1.1.1: {}
+
+ fontace@0.4.1:
+ dependencies:
+ fontkitten: 1.0.3
+
+ fontkitten@1.0.3:
+ dependencies:
+ tiny-inflate: 1.0.3
+
+ form-data@2.5.5:
+ dependencies:
+ asynckit: 0.4.0
+ combined-stream: 1.0.8
+ es-set-tostringtag: 2.1.0
+ hasown: 2.0.2
+ mime-types: 2.1.35
+ safe-buffer: 5.2.1
+
+ fraction.js@5.3.4: {}
+
+ fsevents@2.3.2:
+ optional: true
+
+ fsevents@2.3.3:
+ optional: true
+
+ function-bind@1.1.2: {}
+
+ get-caller-file@2.0.5: {}
+
+ get-intrinsic@1.3.0:
+ dependencies:
+ call-bind-apply-helpers: 1.0.2
+ es-define-property: 1.0.1
+ es-errors: 1.3.0
+ es-object-atoms: 1.1.1
+ function-bind: 1.1.2
+ get-proto: 1.0.1
+ gopd: 1.2.0
+ has-symbols: 1.1.0
+ hasown: 2.0.2
+ math-intrinsics: 1.1.0
+
+ get-port@3.2.0: {}
+
+ get-proto@1.0.1:
+ dependencies:
+ dunder-proto: 1.0.1
+ es-object-atoms: 1.1.1
+
+ get-stream@5.2.0:
+ dependencies:
+ pump: 3.0.4
+
+ git-raw-commits@5.0.1(conventional-commits-parser@6.3.0):
+ dependencies:
+ '@conventional-changelog/git-client': 2.6.0(conventional-commits-parser@6.3.0)
+ meow: 13.2.0
+ transitivePeerDependencies:
+ - conventional-commits-filter
+ - conventional-commits-parser
+
+ github-slugger@2.0.0: {}
+
+ global-directory@4.0.1:
+ dependencies:
+ ini: 4.1.1
+
+ globals@15.15.0: {}
+
+ gopd@1.2.0: {}
+
+ graceful-fs@4.2.11: {}
+
+ h3@1.15.10:
+ dependencies:
+ cookie-es: 1.2.2
+ crossws: 0.3.5
+ defu: 6.1.4
+ destr: 2.0.5
+ iron-webcrypto: 1.2.1
+ node-mock-http: 1.0.4
+ radix3: 1.1.2
+ ufo: 1.6.3
+ uncrypto: 0.1.3
+
+ has-flag@4.0.0: {}
+
+ has-symbols@1.1.0: {}
+
+ has-tostringtag@1.0.2:
+ dependencies:
+ has-symbols: 1.1.0
+
+ hasown@2.0.2:
+ dependencies:
+ function-bind: 1.1.2
+
+ hast-util-from-html@2.0.3:
+ dependencies:
+ '@types/hast': 3.0.4
+ devlop: 1.1.0
+ hast-util-from-parse5: 8.0.3
+ parse5: 7.3.0
+ vfile: 6.0.3
+ vfile-message: 4.0.3
+
+ hast-util-from-parse5@8.0.3:
+ dependencies:
+ '@types/hast': 3.0.4
+ '@types/unist': 3.0.3
+ devlop: 1.1.0
+ hastscript: 9.0.1
+ property-information: 7.1.0
+ vfile: 6.0.3
+ vfile-location: 5.0.3
+ web-namespaces: 2.0.1
+
+ hast-util-is-element@3.0.0:
+ dependencies:
+ '@types/hast': 3.0.4
+
+ hast-util-parse-selector@4.0.0:
+ dependencies:
+ '@types/hast': 3.0.4
+
+ hast-util-raw@9.1.0:
+ dependencies:
+ '@types/hast': 3.0.4
+ '@types/unist': 3.0.3
+ '@ungap/structured-clone': 1.3.0
+ hast-util-from-parse5: 8.0.3
+ hast-util-to-parse5: 8.0.1
+ html-void-elements: 3.0.0
+ mdast-util-to-hast: 13.2.1
+ parse5: 7.3.0
+ unist-util-position: 5.0.0
+ unist-util-visit: 5.1.0
+ vfile: 6.0.3
+ web-namespaces: 2.0.1
+ zwitch: 2.0.4
+
+ hast-util-to-html@9.0.5:
+ dependencies:
+ '@types/hast': 3.0.4
+ '@types/unist': 3.0.3
+ ccount: 2.0.1
+ comma-separated-tokens: 2.0.3
+ hast-util-whitespace: 3.0.0
+ html-void-elements: 3.0.0
+ mdast-util-to-hast: 13.2.1
+ property-information: 7.1.0
+ space-separated-tokens: 2.0.2
+ stringify-entities: 4.0.4
+ zwitch: 2.0.4
+
+ hast-util-to-parse5@8.0.1:
+ dependencies:
+ '@types/hast': 3.0.4
+ comma-separated-tokens: 2.0.3
+ devlop: 1.1.0
+ property-information: 7.1.0
+ space-separated-tokens: 2.0.2
+ web-namespaces: 2.0.1
+ zwitch: 2.0.4
+
+ hast-util-to-text@4.0.2:
+ dependencies:
+ '@types/hast': 3.0.4
+ '@types/unist': 3.0.3
+ hast-util-is-element: 3.0.0
+ unist-util-find-after: 5.0.0
+
+ hast-util-whitespace@3.0.0:
+ dependencies:
+ '@types/hast': 3.0.4
+
+ hastscript@9.0.1:
+ dependencies:
+ '@types/hast': 3.0.4
+ comma-separated-tokens: 2.0.3
+ hast-util-parse-selector: 4.0.0
+ property-information: 7.1.0
+ space-separated-tokens: 2.0.2
+
+ html-encoding-sniffer@6.0.0:
+ dependencies:
+ '@exodus/bytes': 1.15.0
+ transitivePeerDependencies:
+ - '@noble/hashes'
+
+ html-escaper@2.0.2: {}
+
+ html-escaper@3.0.3: {}
+
+ html-void-elements@3.0.0: {}
+
+ htmlparser2@10.1.0:
+ dependencies:
+ domelementtype: 2.3.0
+ domhandler: 5.0.3
+ domutils: 3.2.2
+ entities: 7.0.1
+
+ http-basic@8.1.3:
+ dependencies:
+ caseless: 0.12.0
+ concat-stream: 1.6.2
+ http-response-object: 3.0.2
+ parse-cache-control: 1.0.1
+
+ http-cache-semantics@4.2.0: {}
+
+ http-response-object@3.0.2:
+ dependencies:
+ '@types/node': 10.17.60
+
+ iconv-lite@0.6.3:
+ dependencies:
+ safer-buffer: 2.1.2
+
+ import-fresh@3.3.1:
+ dependencies:
+ parent-module: 1.0.1
+ resolve-from: 4.0.0
+
+ import-meta-resolve@4.2.0: {}
+
+ indent-string@4.0.0: {}
+
+ inherits@2.0.4: {}
+
+ ini@4.1.1: {}
+
+ iron-webcrypto@1.2.1: {}
+
+ is-arrayish@0.2.1: {}
+
+ is-docker@3.0.0: {}
+
+ is-fullwidth-code-point@3.0.0: {}
+
+ is-inside-container@1.0.0:
+ dependencies:
+ is-docker: 3.0.0
+
+ is-obj@2.0.0: {}
+
+ is-plain-obj@4.1.0: {}
+
+ is-potential-custom-element-name@1.0.1: {}
+
+ is-wsl@3.1.1:
+ dependencies:
+ is-inside-container: 1.0.0
+
+ isarray@1.0.0: {}
+
+ istanbul-lib-coverage@3.2.2: {}
+
+ istanbul-lib-report@3.0.1:
+ dependencies:
+ istanbul-lib-coverage: 3.2.2
+ make-dir: 4.0.0
+ supports-color: 7.2.0
+
+ istanbul-reports@3.2.0:
+ dependencies:
+ html-escaper: 2.0.2
+ istanbul-lib-report: 3.0.1
+
+ jiti@2.6.1: {}
+
+ js-tokens@10.0.0: {}
+
+ js-tokens@4.0.0: {}
+
+ js-yaml@4.1.1:
+ dependencies:
+ argparse: 2.0.1
+
+ jsdom@29.0.1:
+ dependencies:
+ '@asamuzakjp/css-color': 5.0.1
+ '@asamuzakjp/dom-selector': 7.0.4
+ '@bramus/specificity': 2.4.2
+ '@csstools/css-syntax-patches-for-csstree': 1.1.1(css-tree@3.2.1)
+ '@exodus/bytes': 1.15.0
+ css-tree: 3.2.1
+ data-urls: 7.0.0
+ decimal.js: 10.6.0
+ html-encoding-sniffer: 6.0.0
+ is-potential-custom-element-name: 1.0.1
+ lru-cache: 11.2.7
+ parse5: 8.0.0
+ saxes: 6.0.0
+ symbol-tree: 3.2.4
+ tough-cookie: 6.0.1
+ undici: 7.24.5
+ w3c-xmlserializer: 5.0.0
+ webidl-conversions: 8.0.1
+ whatwg-mimetype: 5.0.0
+ whatwg-url: 16.0.1
+ xml-name-validator: 5.0.0
+ transitivePeerDependencies:
+ - '@noble/hashes'
+
+ json-parse-even-better-errors@2.3.1: {}
+
+ json-schema-traverse@1.0.0: {}
+
+ jsonc-parser@2.3.1: {}
+
+ jsonc-parser@3.3.1: {}
+
+ jsonschema@1.5.0: {}
+
+ kleur@4.1.5: {}
+
+ kolorist@1.8.0: {}
+
+ lefthook-darwin-arm64@2.1.4:
+ optional: true
+
+ lefthook-darwin-x64@2.1.4:
+ optional: true
+
+ lefthook-freebsd-arm64@2.1.4:
+ optional: true
+
+ lefthook-freebsd-x64@2.1.4:
+ optional: true
+
+ lefthook-linux-arm64@2.1.4:
+ optional: true
+
+ lefthook-linux-x64@2.1.4:
+ optional: true
+
+ lefthook-openbsd-arm64@2.1.4:
+ optional: true
+
+ lefthook-openbsd-x64@2.1.4:
+ optional: true
+
+ lefthook-windows-arm64@2.1.4:
+ optional: true
+
+ lefthook-windows-x64@2.1.4:
+ optional: true
+
+ lefthook@2.1.4:
+ optionalDependencies:
+ lefthook-darwin-arm64: 2.1.4
+ lefthook-darwin-x64: 2.1.4
+ lefthook-freebsd-arm64: 2.1.4
+ lefthook-freebsd-x64: 2.1.4
+ lefthook-linux-arm64: 2.1.4
+ lefthook-linux-x64: 2.1.4
+ lefthook-openbsd-arm64: 2.1.4
+ lefthook-openbsd-x64: 2.1.4
+ lefthook-windows-arm64: 2.1.4
+ lefthook-windows-x64: 2.1.4
+
+ lightningcss-android-arm64@1.32.0:
+ optional: true
+
+ lightningcss-darwin-arm64@1.32.0:
+ optional: true
+
+ lightningcss-darwin-x64@1.32.0:
+ optional: true
+
+ lightningcss-freebsd-x64@1.32.0:
+ optional: true
+
+ lightningcss-linux-arm-gnueabihf@1.32.0:
+ optional: true
+
+ lightningcss-linux-arm64-gnu@1.32.0:
+ optional: true
+
+ lightningcss-linux-arm64-musl@1.32.0:
+ optional: true
+
+ lightningcss-linux-x64-gnu@1.32.0:
+ optional: true
+
+ lightningcss-linux-x64-musl@1.32.0:
+ optional: true
+
+ lightningcss-win32-arm64-msvc@1.32.0:
+ optional: true
+
+ lightningcss-win32-x64-msvc@1.32.0:
+ optional: true
+
+ lightningcss@1.32.0:
+ dependencies:
+ detect-libc: 2.1.2
+ optionalDependencies:
+ lightningcss-android-arm64: 1.32.0
+ lightningcss-darwin-arm64: 1.32.0
+ lightningcss-darwin-x64: 1.32.0
+ lightningcss-freebsd-x64: 1.32.0
+ lightningcss-linux-arm-gnueabihf: 1.32.0
+ lightningcss-linux-arm64-gnu: 1.32.0
+ lightningcss-linux-arm64-musl: 1.32.0
+ lightningcss-linux-x64-gnu: 1.32.0
+ lightningcss-linux-x64-musl: 1.32.0
+ lightningcss-win32-arm64-msvc: 1.32.0
+ lightningcss-win32-x64-msvc: 1.32.0
+
+ lines-and-columns@1.2.4: {}
+
+ local-pkg@1.1.2:
+ dependencies:
+ mlly: 1.8.2
+ pkg-types: 2.3.0
+ quansync: 0.2.11
+
+ lodash.camelcase@4.3.0: {}
+
+ lodash.kebabcase@4.1.1: {}
+
+ lodash.mergewith@4.6.2: {}
+
+ lodash.snakecase@4.1.1: {}
+
+ lodash.startcase@4.4.0: {}
+
+ lodash.upperfirst@4.3.1: {}
+
+ longest-streak@3.1.0: {}
+
+ lru-cache@11.2.7: {}
+
+ magic-string@0.30.21:
+ dependencies:
+ '@jridgewell/sourcemap-codec': 1.5.5
+
+ magicast@0.5.2:
+ dependencies:
+ '@babel/parser': 7.29.2
+ '@babel/types': 7.29.0
+ source-map-js: 1.2.1
+
+ make-dir@4.0.0:
+ dependencies:
+ semver: 7.7.4
+
+ markdown-table@3.0.4: {}
+
+ math-intrinsics@1.1.0: {}
+
+ mdast-util-definitions@6.0.0:
+ dependencies:
+ '@types/mdast': 4.0.4
+ '@types/unist': 3.0.3
+ unist-util-visit: 5.1.0
+
+ mdast-util-find-and-replace@3.0.2:
+ dependencies:
+ '@types/mdast': 4.0.4
+ escape-string-regexp: 5.0.0
+ unist-util-is: 6.0.1
+ unist-util-visit-parents: 6.0.2
+
+ mdast-util-from-markdown@2.0.3:
+ dependencies:
+ '@types/mdast': 4.0.4
+ '@types/unist': 3.0.3
+ decode-named-character-reference: 1.3.0
+ devlop: 1.1.0
+ mdast-util-to-string: 4.0.0
+ micromark: 4.0.2
+ micromark-util-decode-numeric-character-reference: 2.0.2
+ micromark-util-decode-string: 2.0.1
+ micromark-util-normalize-identifier: 2.0.1
+ micromark-util-symbol: 2.0.1
+ micromark-util-types: 2.0.2
+ unist-util-stringify-position: 4.0.0
+ transitivePeerDependencies:
+ - supports-color
+
+ mdast-util-gfm-autolink-literal@2.0.1:
+ dependencies:
+ '@types/mdast': 4.0.4
+ ccount: 2.0.1
+ devlop: 1.1.0
+ mdast-util-find-and-replace: 3.0.2
+ micromark-util-character: 2.1.1
+
+ mdast-util-gfm-footnote@2.1.0:
+ dependencies:
+ '@types/mdast': 4.0.4
+ devlop: 1.1.0
+ mdast-util-from-markdown: 2.0.3
+ mdast-util-to-markdown: 2.1.2
+ micromark-util-normalize-identifier: 2.0.1
+ transitivePeerDependencies:
+ - supports-color
+
+ mdast-util-gfm-strikethrough@2.0.0:
+ dependencies:
+ '@types/mdast': 4.0.4
+ mdast-util-from-markdown: 2.0.3
+ mdast-util-to-markdown: 2.1.2
+ transitivePeerDependencies:
+ - supports-color
+
+ mdast-util-gfm-table@2.0.0:
+ dependencies:
+ '@types/mdast': 4.0.4
+ devlop: 1.1.0
+ markdown-table: 3.0.4
+ mdast-util-from-markdown: 2.0.3
+ mdast-util-to-markdown: 2.1.2
+ transitivePeerDependencies:
+ - supports-color
+
+ mdast-util-gfm-task-list-item@2.0.0:
+ dependencies:
+ '@types/mdast': 4.0.4
+ devlop: 1.1.0
+ mdast-util-from-markdown: 2.0.3
+ mdast-util-to-markdown: 2.1.2
+ transitivePeerDependencies:
+ - supports-color
+
+ mdast-util-gfm@3.1.0:
+ dependencies:
+ mdast-util-from-markdown: 2.0.3
+ mdast-util-gfm-autolink-literal: 2.0.1
+ mdast-util-gfm-footnote: 2.1.0
+ mdast-util-gfm-strikethrough: 2.0.0
+ mdast-util-gfm-table: 2.0.0
+ mdast-util-gfm-task-list-item: 2.0.0
+ mdast-util-to-markdown: 2.1.2
+ transitivePeerDependencies:
+ - supports-color
+
+ mdast-util-phrasing@4.1.0:
+ dependencies:
+ '@types/mdast': 4.0.4
+ unist-util-is: 6.0.1
+
+ mdast-util-to-hast@13.2.1:
+ dependencies:
+ '@types/hast': 3.0.4
+ '@types/mdast': 4.0.4
+ '@ungap/structured-clone': 1.3.0
+ devlop: 1.1.0
+ micromark-util-sanitize-uri: 2.0.1
+ trim-lines: 3.0.1
+ unist-util-position: 5.0.0
+ unist-util-visit: 5.1.0
+ vfile: 6.0.3
+
+ mdast-util-to-markdown@2.1.2:
+ dependencies:
+ '@types/mdast': 4.0.4
+ '@types/unist': 3.0.3
+ longest-streak: 3.1.0
+ mdast-util-phrasing: 4.1.0
+ mdast-util-to-string: 4.0.0
+ micromark-util-classify-character: 2.0.1
+ micromark-util-decode-string: 2.0.1
+ unist-util-visit: 5.1.0
+ zwitch: 2.0.4
+
+ mdast-util-to-string@4.0.0:
+ dependencies:
+ '@types/mdast': 4.0.4
+
+ mdn-data@2.0.28: {}
+
+ mdn-data@2.0.30: {}
+
+ mdn-data@2.27.1: {}
+
+ meow@13.2.0: {}
+
+ metagroup-schema-tools@1.1.0:
+ dependencies:
+ jsonschema: 1.5.0
+ moment: 2.30.1
+ rss-parser: 3.13.0
+ sync-request: 6.1.0
+
+ micromark-core-commonmark@2.0.3:
+ dependencies:
+ decode-named-character-reference: 1.3.0
+ devlop: 1.1.0
+ micromark-factory-destination: 2.0.1
+ micromark-factory-label: 2.0.1
+ micromark-factory-space: 2.0.1
+ micromark-factory-title: 2.0.1
+ micromark-factory-whitespace: 2.0.1
+ micromark-util-character: 2.1.1
+ micromark-util-chunked: 2.0.1
+ micromark-util-classify-character: 2.0.1
+ micromark-util-html-tag-name: 2.0.1
+ micromark-util-normalize-identifier: 2.0.1
+ micromark-util-resolve-all: 2.0.1
+ micromark-util-subtokenize: 2.1.0
+ micromark-util-symbol: 2.0.1
+ micromark-util-types: 2.0.2
+
+ micromark-extension-gfm-autolink-literal@2.1.0:
+ dependencies:
+ micromark-util-character: 2.1.1
+ micromark-util-sanitize-uri: 2.0.1
+ micromark-util-symbol: 2.0.1
+ micromark-util-types: 2.0.2
+
+ micromark-extension-gfm-footnote@2.1.0:
+ dependencies:
+ devlop: 1.1.0
+ micromark-core-commonmark: 2.0.3
+ micromark-factory-space: 2.0.1
+ micromark-util-character: 2.1.1
+ micromark-util-normalize-identifier: 2.0.1
+ micromark-util-sanitize-uri: 2.0.1
+ micromark-util-symbol: 2.0.1
+ micromark-util-types: 2.0.2
+
+ micromark-extension-gfm-strikethrough@2.1.0:
+ dependencies:
+ devlop: 1.1.0
+ micromark-util-chunked: 2.0.1
+ micromark-util-classify-character: 2.0.1
+ micromark-util-resolve-all: 2.0.1
+ micromark-util-symbol: 2.0.1
+ micromark-util-types: 2.0.2
+
+ micromark-extension-gfm-table@2.1.1:
+ dependencies:
+ devlop: 1.1.0
+ micromark-factory-space: 2.0.1
+ micromark-util-character: 2.1.1
+ micromark-util-symbol: 2.0.1
+ micromark-util-types: 2.0.2
+
+ micromark-extension-gfm-tagfilter@2.0.0:
+ dependencies:
+ micromark-util-types: 2.0.2
+
+ micromark-extension-gfm-task-list-item@2.1.0:
+ dependencies:
+ devlop: 1.1.0
+ micromark-factory-space: 2.0.1
+ micromark-util-character: 2.1.1
+ micromark-util-symbol: 2.0.1
+ micromark-util-types: 2.0.2
+
+ micromark-extension-gfm@3.0.0:
+ dependencies:
+ micromark-extension-gfm-autolink-literal: 2.1.0
+ micromark-extension-gfm-footnote: 2.1.0
+ micromark-extension-gfm-strikethrough: 2.1.0
+ micromark-extension-gfm-table: 2.1.1
+ micromark-extension-gfm-tagfilter: 2.0.0
+ micromark-extension-gfm-task-list-item: 2.1.0
+ micromark-util-combine-extensions: 2.0.1
+ micromark-util-types: 2.0.2
+
+ micromark-factory-destination@2.0.1:
+ dependencies:
+ micromark-util-character: 2.1.1
+ micromark-util-symbol: 2.0.1
+ micromark-util-types: 2.0.2
+
+ micromark-factory-label@2.0.1:
+ dependencies:
+ devlop: 1.1.0
+ micromark-util-character: 2.1.1
+ micromark-util-symbol: 2.0.1
+ micromark-util-types: 2.0.2
+
+ micromark-factory-space@2.0.1:
+ dependencies:
+ micromark-util-character: 2.1.1
+ micromark-util-types: 2.0.2
+
+ micromark-factory-title@2.0.1:
+ dependencies:
+ micromark-factory-space: 2.0.1
+ micromark-util-character: 2.1.1
+ micromark-util-symbol: 2.0.1
+ micromark-util-types: 2.0.2
+
+ micromark-factory-whitespace@2.0.1:
+ dependencies:
+ micromark-factory-space: 2.0.1
+ micromark-util-character: 2.1.1
+ micromark-util-symbol: 2.0.1
+ micromark-util-types: 2.0.2
+
+ micromark-util-character@2.1.1:
+ dependencies:
+ micromark-util-symbol: 2.0.1
+ micromark-util-types: 2.0.2
+
+ micromark-util-chunked@2.0.1:
+ dependencies:
+ micromark-util-symbol: 2.0.1
+
+ micromark-util-classify-character@2.0.1:
+ dependencies:
+ micromark-util-character: 2.1.1
+ micromark-util-symbol: 2.0.1
+ micromark-util-types: 2.0.2
+
+ micromark-util-combine-extensions@2.0.1:
+ dependencies:
+ micromark-util-chunked: 2.0.1
+ micromark-util-types: 2.0.2
+
+ micromark-util-decode-numeric-character-reference@2.0.2:
+ dependencies:
+ micromark-util-symbol: 2.0.1
+
+ micromark-util-decode-string@2.0.1:
+ dependencies:
+ decode-named-character-reference: 1.3.0
+ micromark-util-character: 2.1.1
+ micromark-util-decode-numeric-character-reference: 2.0.2
+ micromark-util-symbol: 2.0.1
+
+ micromark-util-encode@2.0.1: {}
+
+ micromark-util-html-tag-name@2.0.1: {}
+
+ micromark-util-normalize-identifier@2.0.1:
+ dependencies:
+ micromark-util-symbol: 2.0.1
+
+ micromark-util-resolve-all@2.0.1:
+ dependencies:
+ micromark-util-types: 2.0.2
+
+ micromark-util-sanitize-uri@2.0.1:
+ dependencies:
+ micromark-util-character: 2.1.1
+ micromark-util-encode: 2.0.1
+ micromark-util-symbol: 2.0.1
+
+ micromark-util-subtokenize@2.1.0:
+ dependencies:
+ devlop: 1.1.0
+ micromark-util-chunked: 2.0.1
+ micromark-util-symbol: 2.0.1
+ micromark-util-types: 2.0.2
+
+ micromark-util-symbol@2.0.1: {}
+
+ micromark-util-types@2.0.2: {}
+
+ micromark@4.0.2:
+ dependencies:
+ '@types/debug': 4.1.13
+ debug: 4.4.3
+ decode-named-character-reference: 1.3.0
+ devlop: 1.1.0
+ micromark-core-commonmark: 2.0.3
+ micromark-factory-space: 2.0.1
+ micromark-util-character: 2.1.1
+ micromark-util-chunked: 2.0.1
+ micromark-util-combine-extensions: 2.0.1
+ micromark-util-decode-numeric-character-reference: 2.0.2
+ micromark-util-encode: 2.0.1
+ micromark-util-normalize-identifier: 2.0.1
+ micromark-util-resolve-all: 2.0.1
+ micromark-util-sanitize-uri: 2.0.1
+ micromark-util-subtokenize: 2.1.0
+ micromark-util-symbol: 2.0.1
+ micromark-util-types: 2.0.2
+ transitivePeerDependencies:
+ - supports-color
+
+ mime-db@1.52.0: {}
+
+ mime-types@2.1.35:
+ dependencies:
+ mime-db: 1.52.0
+
+ min-indent@1.0.1: {}
+
+ minimist@1.2.8: {}
+
+ minipass@7.1.3: {}
+
+ minizlib@3.1.0:
+ dependencies:
+ minipass: 7.1.3
+
+ mlly@1.8.2:
+ dependencies:
+ acorn: 8.16.0
+ pathe: 2.0.3
+ pkg-types: 1.3.1
+ ufo: 1.6.3
+
+ moment@2.30.1: {}
+
+ mrmime@2.0.1: {}
+
+ ms@2.1.3: {}
+
+ muggle-string@0.4.1: {}
+
+ nanoid@3.3.11: {}
+
+ neotraverse@0.6.18: {}
+
+ nlcst-to-string@4.0.0:
+ dependencies:
+ '@types/nlcst': 2.0.3
+
+ node-fetch-native@1.6.7: {}
+
+ node-mock-http@1.0.4: {}
+
+ node-releases@2.0.36: {}
+
+ normalize-path@3.0.0: {}
+
+ nth-check@2.1.1:
+ dependencies:
+ boolbase: 1.0.0
+
+ object-inspect@1.13.4: {}
+
+ obug@2.1.1: {}
+
+ ofetch@1.5.1:
+ dependencies:
+ destr: 2.0.5
+ node-fetch-native: 1.6.7
+ ufo: 1.6.3
+
+ ohash@2.0.11: {}
+
+ once@1.4.0:
+ dependencies:
+ wrappy: 1.0.2
+
+ oniguruma-parser@0.12.1: {}
+
+ oniguruma-to-es@4.3.5:
+ dependencies:
+ oniguruma-parser: 0.12.1
+ regex: 6.1.0
+ regex-recursion: 6.0.2
+
+ oxfmt@0.41.0:
+ dependencies:
+ tinypool: 2.1.0
+ optionalDependencies:
+ '@oxfmt/binding-android-arm-eabi': 0.41.0
+ '@oxfmt/binding-android-arm64': 0.41.0
+ '@oxfmt/binding-darwin-arm64': 0.41.0
+ '@oxfmt/binding-darwin-x64': 0.41.0
+ '@oxfmt/binding-freebsd-x64': 0.41.0
+ '@oxfmt/binding-linux-arm-gnueabihf': 0.41.0
+ '@oxfmt/binding-linux-arm-musleabihf': 0.41.0
+ '@oxfmt/binding-linux-arm64-gnu': 0.41.0
+ '@oxfmt/binding-linux-arm64-musl': 0.41.0
+ '@oxfmt/binding-linux-ppc64-gnu': 0.41.0
+ '@oxfmt/binding-linux-riscv64-gnu': 0.41.0
+ '@oxfmt/binding-linux-riscv64-musl': 0.41.0
+ '@oxfmt/binding-linux-s390x-gnu': 0.41.0
+ '@oxfmt/binding-linux-x64-gnu': 0.41.0
+ '@oxfmt/binding-linux-x64-musl': 0.41.0
+ '@oxfmt/binding-openharmony-arm64': 0.41.0
+ '@oxfmt/binding-win32-arm64-msvc': 0.41.0
+ '@oxfmt/binding-win32-ia32-msvc': 0.41.0
+ '@oxfmt/binding-win32-x64-msvc': 0.41.0
+
+ oxlint@1.56.0:
+ optionalDependencies:
+ '@oxlint/binding-android-arm-eabi': 1.56.0
+ '@oxlint/binding-android-arm64': 1.56.0
+ '@oxlint/binding-darwin-arm64': 1.56.0
+ '@oxlint/binding-darwin-x64': 1.56.0
+ '@oxlint/binding-freebsd-x64': 1.56.0
+ '@oxlint/binding-linux-arm-gnueabihf': 1.56.0
+ '@oxlint/binding-linux-arm-musleabihf': 1.56.0
+ '@oxlint/binding-linux-arm64-gnu': 1.56.0
+ '@oxlint/binding-linux-arm64-musl': 1.56.0
+ '@oxlint/binding-linux-ppc64-gnu': 1.56.0
+ '@oxlint/binding-linux-riscv64-gnu': 1.56.0
+ '@oxlint/binding-linux-riscv64-musl': 1.56.0
+ '@oxlint/binding-linux-s390x-gnu': 1.56.0
+ '@oxlint/binding-linux-x64-gnu': 1.56.0
+ '@oxlint/binding-linux-x64-musl': 1.56.0
+ '@oxlint/binding-openharmony-arm64': 1.56.0
+ '@oxlint/binding-win32-arm64-msvc': 1.56.0
+ '@oxlint/binding-win32-ia32-msvc': 1.56.0
+ '@oxlint/binding-win32-x64-msvc': 1.56.0
+
+ p-limit@7.3.0:
+ dependencies:
+ yocto-queue: 1.2.2
+
+ p-queue@9.1.0:
+ dependencies:
+ eventemitter3: 5.0.4
+ p-timeout: 7.0.1
+
+ p-timeout@7.0.1: {}
+
+ package-manager-detector@1.6.0: {}
+
+ parent-module@1.0.1:
+ dependencies:
+ callsites: 3.1.0
+
+ parse-cache-control@1.0.1: {}
+
+ parse-json@5.2.0:
+ dependencies:
+ '@babel/code-frame': 7.29.0
+ error-ex: 1.3.4
+ json-parse-even-better-errors: 2.3.1
+ lines-and-columns: 1.2.4
+
+ parse-latin@7.0.0:
+ dependencies:
+ '@types/nlcst': 2.0.3
+ '@types/unist': 3.0.3
+ nlcst-to-string: 4.0.0
+ unist-util-modify-children: 4.0.0
+ unist-util-visit-children: 3.0.0
+ vfile: 6.0.3
+
+ parse5-htmlparser2-tree-adapter@7.1.0:
+ dependencies:
+ domhandler: 5.0.3
+ parse5: 7.3.0
+
+ parse5-parser-stream@7.1.2:
+ dependencies:
+ parse5: 7.3.0
+
+ parse5@7.3.0:
+ dependencies:
+ entities: 6.0.1
+
+ parse5@8.0.0:
+ dependencies:
+ entities: 6.0.1
+
+ path-browserify@1.0.1: {}
+
+ pathe@2.0.3: {}
+
+ pend@1.2.0: {}
+
+ piccolore@0.1.3: {}
+
+ picocolors@1.1.1: {}
+
+ picomatch@2.3.1: {}
+
+ picomatch@4.0.3: {}
+
+ pkg-types@1.3.1:
+ dependencies:
+ confbox: 0.1.8
+ mlly: 1.8.2
+ pathe: 2.0.3
+
+ pkg-types@2.3.0:
+ dependencies:
+ confbox: 0.2.4
+ exsolve: 1.0.8
+ pathe: 2.0.3
+
+ playwright-core@1.58.2: {}
+
+ playwright@1.58.2:
+ dependencies:
+ playwright-core: 1.58.2
+ optionalDependencies:
+ fsevents: 2.3.2
+
+ postcss-value-parser@4.2.0: {}
+
+ postcss@8.5.8:
+ dependencies:
+ nanoid: 3.3.11
+ picocolors: 1.1.1
+ source-map-js: 1.2.1
+
+ prettier@3.8.1: {}
+
+ prismjs@1.30.0: {}
+
+ process-nextick-args@2.0.1: {}
+
+ promise@8.3.0:
+ dependencies:
+ asap: 2.0.6
+
+ property-information@7.1.0: {}
+
+ pump@3.0.4:
+ dependencies:
+ end-of-stream: 1.4.5
+ once: 1.4.0
+
+ punycode@2.3.1: {}
+
+ qs@6.15.0:
+ dependencies:
+ side-channel: 1.1.0
+
+ quansync@0.2.11: {}
+
+ radix3@1.1.2: {}
+
+ react-dom@19.2.4(react@19.2.4):
+ dependencies:
+ react: 19.2.4
+ scheduler: 0.27.0
+ optional: true
+
+ react@19.2.4:
+ optional: true
+
+ readable-stream@2.3.8:
+ dependencies:
+ core-util-is: 1.0.3
+ inherits: 2.0.4
+ isarray: 1.0.0
+ process-nextick-args: 2.0.1
+ safe-buffer: 5.1.2
+ string_decoder: 1.1.1
+ util-deprecate: 1.0.2
+
+ readdirp@4.1.2: {}
+
+ readdirp@5.0.0: {}
+
+ redent@3.0.0:
+ dependencies:
+ indent-string: 4.0.0
+ strip-indent: 3.0.0
+
+ regex-recursion@6.0.2:
+ dependencies:
+ regex-utilities: 2.3.0
+
+ regex-utilities@2.3.0: {}
+
+ regex@6.1.0:
+ dependencies:
+ regex-utilities: 2.3.0
+
+ rehype-parse@9.0.1:
+ dependencies:
+ '@types/hast': 3.0.4
+ hast-util-from-html: 2.0.3
+ unified: 11.0.5
+
+ rehype-raw@7.0.0:
+ dependencies:
+ '@types/hast': 3.0.4
+ hast-util-raw: 9.1.0
+ vfile: 6.0.3
+
+ rehype-stringify@10.0.1:
+ dependencies:
+ '@types/hast': 3.0.4
+ hast-util-to-html: 9.0.5
+ unified: 11.0.5
+
+ rehype@13.0.2:
+ dependencies:
+ '@types/hast': 3.0.4
+ rehype-parse: 9.0.1
+ rehype-stringify: 10.0.1
+ unified: 11.0.5
+
+ remark-gfm@4.0.1:
+ dependencies:
+ '@types/mdast': 4.0.4
+ mdast-util-gfm: 3.1.0
+ micromark-extension-gfm: 3.0.0
+ remark-parse: 11.0.0
+ remark-stringify: 11.0.0
+ unified: 11.0.5
+ transitivePeerDependencies:
+ - supports-color
+
+ remark-parse@11.0.0:
+ dependencies:
+ '@types/mdast': 4.0.4
+ mdast-util-from-markdown: 2.0.3
+ micromark-util-types: 2.0.2
+ unified: 11.0.5
+ transitivePeerDependencies:
+ - supports-color
+
+ remark-rehype@11.1.2:
+ dependencies:
+ '@types/hast': 3.0.4
+ '@types/mdast': 4.0.4
+ mdast-util-to-hast: 13.2.1
+ unified: 11.0.5
+ vfile: 6.0.3
+
+ remark-smartypants@3.0.2:
+ dependencies:
+ retext: 9.0.0
+ retext-smartypants: 6.2.0
+ unified: 11.0.5
+ unist-util-visit: 5.1.0
+
+ remark-stringify@11.0.0:
+ dependencies:
+ '@types/mdast': 4.0.4
+ mdast-util-to-markdown: 2.1.2
+ unified: 11.0.5
+
+ request-light@0.5.8: {}
+
+ request-light@0.7.0: {}
+
+ require-directory@2.1.1: {}
+
+ require-from-string@2.0.2: {}
+
+ resolve-from@4.0.0: {}
+
+ resolve-from@5.0.0: {}
+
+ retext-latin@4.0.0:
+ dependencies:
+ '@types/nlcst': 2.0.3
+ parse-latin: 7.0.0
+ unified: 11.0.5
+
+ retext-smartypants@6.2.0:
+ dependencies:
+ '@types/nlcst': 2.0.3
+ nlcst-to-string: 4.0.0
+ unist-util-visit: 5.1.0
+
+ retext-stringify@4.0.0:
+ dependencies:
+ '@types/nlcst': 2.0.3
+ nlcst-to-string: 4.0.0
+ unified: 11.0.5
+
+ retext@9.0.0:
+ dependencies:
+ '@types/nlcst': 2.0.3
+ retext-latin: 4.0.0
+ retext-stringify: 4.0.0
+ unified: 11.0.5
+
+ rollup@4.60.0:
+ dependencies:
+ '@types/estree': 1.0.8
+ optionalDependencies:
+ '@rollup/rollup-android-arm-eabi': 4.60.0
+ '@rollup/rollup-android-arm64': 4.60.0
+ '@rollup/rollup-darwin-arm64': 4.60.0
+ '@rollup/rollup-darwin-x64': 4.60.0
+ '@rollup/rollup-freebsd-arm64': 4.60.0
+ '@rollup/rollup-freebsd-x64': 4.60.0
+ '@rollup/rollup-linux-arm-gnueabihf': 4.60.0
+ '@rollup/rollup-linux-arm-musleabihf': 4.60.0
+ '@rollup/rollup-linux-arm64-gnu': 4.60.0
+ '@rollup/rollup-linux-arm64-musl': 4.60.0
+ '@rollup/rollup-linux-loong64-gnu': 4.60.0
+ '@rollup/rollup-linux-loong64-musl': 4.60.0
+ '@rollup/rollup-linux-ppc64-gnu': 4.60.0
+ '@rollup/rollup-linux-ppc64-musl': 4.60.0
+ '@rollup/rollup-linux-riscv64-gnu': 4.60.0
+ '@rollup/rollup-linux-riscv64-musl': 4.60.0
+ '@rollup/rollup-linux-s390x-gnu': 4.60.0
+ '@rollup/rollup-linux-x64-gnu': 4.60.0
+ '@rollup/rollup-linux-x64-musl': 4.60.0
+ '@rollup/rollup-openbsd-x64': 4.60.0
+ '@rollup/rollup-openharmony-arm64': 4.60.0
+ '@rollup/rollup-win32-arm64-msvc': 4.60.0
+ '@rollup/rollup-win32-ia32-msvc': 4.60.0
+ '@rollup/rollup-win32-x64-gnu': 4.60.0
+ '@rollup/rollup-win32-x64-msvc': 4.60.0
+ fsevents: 2.3.3
+
+ rss-parser@3.13.0:
+ dependencies:
+ entities: 2.2.0
+ xml2js: 0.5.0
+
+ safe-buffer@5.1.2: {}
+
+ safe-buffer@5.2.1: {}
+
+ safer-buffer@2.1.2: {}
+
+ sax@1.6.0: {}
+
+ saxes@6.0.0:
+ dependencies:
+ xmlchars: 2.2.0
+
+ scheduler@0.27.0:
+ optional: true
+
+ semver@7.7.4: {}
+
+ shaders@2.4.78(react-dom@19.2.4(react@19.2.4))(react@19.2.4):
+ dependencies:
+ three: 0.183.2
+ optionalDependencies:
+ react: 19.2.4
+ react-dom: 19.2.4(react@19.2.4)
+
+ sharp@0.34.5:
+ dependencies:
+ '@img/colour': 1.1.0
+ detect-libc: 2.1.2
+ semver: 7.7.4
+ optionalDependencies:
+ '@img/sharp-darwin-arm64': 0.34.5
+ '@img/sharp-darwin-x64': 0.34.5
+ '@img/sharp-libvips-darwin-arm64': 1.2.4
+ '@img/sharp-libvips-darwin-x64': 1.2.4
+ '@img/sharp-libvips-linux-arm': 1.2.4
+ '@img/sharp-libvips-linux-arm64': 1.2.4
+ '@img/sharp-libvips-linux-ppc64': 1.2.4
+ '@img/sharp-libvips-linux-riscv64': 1.2.4
+ '@img/sharp-libvips-linux-s390x': 1.2.4
+ '@img/sharp-libvips-linux-x64': 1.2.4
+ '@img/sharp-libvips-linuxmusl-arm64': 1.2.4
+ '@img/sharp-libvips-linuxmusl-x64': 1.2.4
+ '@img/sharp-linux-arm': 0.34.5
+ '@img/sharp-linux-arm64': 0.34.5
+ '@img/sharp-linux-ppc64': 0.34.5
+ '@img/sharp-linux-riscv64': 0.34.5
+ '@img/sharp-linux-s390x': 0.34.5
+ '@img/sharp-linux-x64': 0.34.5
+ '@img/sharp-linuxmusl-arm64': 0.34.5
+ '@img/sharp-linuxmusl-x64': 0.34.5
+ '@img/sharp-wasm32': 0.34.5
+ '@img/sharp-win32-arm64': 0.34.5
+ '@img/sharp-win32-ia32': 0.34.5
+ '@img/sharp-win32-x64': 0.34.5
+ optional: true
+
+ shiki@4.0.2:
+ dependencies:
+ '@shikijs/core': 4.0.2
+ '@shikijs/engine-javascript': 4.0.2
+ '@shikijs/engine-oniguruma': 4.0.2
+ '@shikijs/langs': 4.0.2
+ '@shikijs/themes': 4.0.2
+ '@shikijs/types': 4.0.2
+ '@shikijs/vscode-textmate': 10.0.2
+ '@types/hast': 3.0.4
+
+ side-channel-list@1.0.0:
+ dependencies:
+ es-errors: 1.3.0
+ object-inspect: 1.13.4
+
+ side-channel-map@1.0.1:
+ dependencies:
+ call-bound: 1.0.4
+ es-errors: 1.3.0
+ get-intrinsic: 1.3.0
+ object-inspect: 1.13.4
+
+ side-channel-weakmap@1.0.2:
+ dependencies:
+ call-bound: 1.0.4
+ es-errors: 1.3.0
+ get-intrinsic: 1.3.0
+ object-inspect: 1.13.4
+ side-channel-map: 1.0.1
+
+ side-channel@1.1.0:
+ dependencies:
+ es-errors: 1.3.0
+ object-inspect: 1.13.4
+ side-channel-list: 1.0.0
+ side-channel-map: 1.0.1
+ side-channel-weakmap: 1.0.2
+
+ siginfo@2.0.0: {}
+
+ sirv@3.0.2:
+ dependencies:
+ '@polka/url': 1.0.0-next.29
+ mrmime: 2.0.1
+ totalist: 3.0.1
+
+ sisteransi@1.0.5: {}
+
+ smol-toml@1.6.1: {}
+
+ source-map-js@1.2.1: {}
+
+ space-separated-tokens@2.0.2: {}
+
+ stackback@0.0.2: {}
+
+ std-env@4.0.0: {}
+
+ string-width@4.2.3:
+ dependencies:
+ emoji-regex: 8.0.0
+ is-fullwidth-code-point: 3.0.0
+ strip-ansi: 6.0.1
+
+ string_decoder@1.1.1:
+ dependencies:
+ safe-buffer: 5.1.2
+
+ stringify-entities@4.0.4:
+ dependencies:
+ character-entities-html4: 2.1.0
+ character-entities-legacy: 3.0.0
+
+ strip-ansi@6.0.1:
+ dependencies:
+ ansi-regex: 5.0.1
+
+ strip-indent@3.0.0:
+ dependencies:
+ min-indent: 1.0.1
+
+ supports-color@7.2.0:
+ dependencies:
+ has-flag: 4.0.0
+
+ svgo@3.3.3:
+ dependencies:
+ commander: 7.2.0
+ css-select: 5.2.2
+ css-tree: 2.3.1
+ css-what: 6.2.2
+ csso: 5.0.5
+ picocolors: 1.1.1
+ sax: 1.6.0
+
+ svgo@4.0.1:
+ dependencies:
+ commander: 11.1.0
+ css-select: 5.2.2
+ css-tree: 3.2.1
+ css-what: 6.2.2
+ csso: 5.0.5
+ picocolors: 1.1.1
+ sax: 1.6.0
+
+ symbol-tree@3.2.4: {}
+
+ sync-request@6.1.0:
+ dependencies:
+ http-response-object: 3.0.2
+ sync-rpc: 1.3.6
+ then-request: 6.0.2
+
+ sync-rpc@1.3.6:
+ dependencies:
+ get-port: 3.2.0
+
+ tailwindcss@4.2.2: {}
+
+ tapable@2.3.1: {}
+
+ tar@7.5.13:
+ dependencies:
+ '@isaacs/fs-minipass': 4.0.1
+ chownr: 3.0.0
+ minipass: 7.1.3
+ minizlib: 3.1.0
+ yallist: 5.0.0
+
+ then-request@6.0.2:
+ dependencies:
+ '@types/concat-stream': 1.6.1
+ '@types/form-data': 0.0.33
+ '@types/node': 8.10.66
+ '@types/qs': 6.15.0
+ caseless: 0.12.0
+ concat-stream: 1.6.2
+ form-data: 2.5.5
+ http-basic: 8.1.3
+ http-response-object: 3.0.2
+ promise: 8.3.0
+ qs: 6.15.0
+
+ three@0.183.2: {}
+
+ tiny-inflate@1.0.3: {}
+
+ tinybench@2.9.0: {}
+
+ tinyclip@0.1.12: {}
+
+ tinyexec@1.0.4: {}
+
+ tinyglobby@0.2.15:
+ dependencies:
+ fdir: 6.5.0(picomatch@4.0.3)
+ picomatch: 4.0.3
+
+ tinypool@2.1.0: {}
+
+ tinyrainbow@3.1.0: {}
+
+ tldts-core@7.0.27: {}
+
+ tldts@7.0.27:
+ dependencies:
+ tldts-core: 7.0.27
+
+ totalist@3.0.1: {}
+
+ tough-cookie@6.0.1:
+ dependencies:
+ tldts: 7.0.27
+
+ tr46@6.0.0:
+ dependencies:
+ punycode: 2.3.1
+
+ trim-lines@3.0.1: {}
+
+ trough@2.2.0: {}
+
+ tsconfck@3.1.6(typescript@5.9.3):
+ optionalDependencies:
+ typescript: 5.9.3
+
+ tslib@2.8.1:
+ optional: true
+
+ typedarray@0.0.6: {}
+
+ typesafe-path@0.2.2: {}
+
+ typescript-auto-import-cache@0.3.6:
+ dependencies:
+ semver: 7.7.4
+
+ typescript@5.9.3: {}
+
+ ufo@1.6.3: {}
+
+ ultrahtml@1.6.0: {}
+
+ uncrypto@0.1.3: {}
+
+ undici-types@7.18.2: {}
+
+ undici@7.24.5: {}
+
+ unified@11.0.5:
+ dependencies:
+ '@types/unist': 3.0.3
+ bail: 2.0.2
+ devlop: 1.1.0
+ extend: 3.0.2
+ is-plain-obj: 4.1.0
+ trough: 2.2.0
+ vfile: 6.0.3
+
+ unifont@0.7.4:
+ dependencies:
+ css-tree: 3.2.1
+ ofetch: 1.5.1
+ ohash: 2.0.11
+
+ unist-util-find-after@5.0.0:
+ dependencies:
+ '@types/unist': 3.0.3
+ unist-util-is: 6.0.1
+
+ unist-util-is@6.0.1:
+ dependencies:
+ '@types/unist': 3.0.3
+
+ unist-util-modify-children@4.0.0:
+ dependencies:
+ '@types/unist': 3.0.3
+ array-iterate: 2.0.1
+
+ unist-util-position@5.0.0:
+ dependencies:
+ '@types/unist': 3.0.3
+
+ unist-util-remove-position@5.0.0:
+ dependencies:
+ '@types/unist': 3.0.3
+ unist-util-visit: 5.1.0
+
+ unist-util-stringify-position@4.0.0:
+ dependencies:
+ '@types/unist': 3.0.3
+
+ unist-util-visit-children@3.0.0:
+ dependencies:
+ '@types/unist': 3.0.3
+
+ unist-util-visit-parents@6.0.2:
+ dependencies:
+ '@types/unist': 3.0.3
+ unist-util-is: 6.0.1
+
+ unist-util-visit@5.1.0:
+ dependencies:
+ '@types/unist': 3.0.3
+ unist-util-is: 6.0.1
+ unist-util-visit-parents: 6.0.2
+
+ unstorage@1.17.4:
+ dependencies:
+ anymatch: 3.1.3
+ chokidar: 5.0.0
+ destr: 2.0.5
+ h3: 1.15.10
+ lru-cache: 11.2.7
+ node-fetch-native: 1.6.7
+ ofetch: 1.5.1
+ ufo: 1.6.3
+
+ update-browserslist-db@1.2.3(browserslist@4.28.1):
+ dependencies:
+ browserslist: 4.28.1
+ escalade: 3.2.0
+ picocolors: 1.1.1
+
+ util-deprecate@1.0.2: {}
+
+ vfile-location@5.0.3:
+ dependencies:
+ '@types/unist': 3.0.3
+ vfile: 6.0.3
+
+ vfile-message@4.0.3:
+ dependencies:
+ '@types/unist': 3.0.3
+ unist-util-stringify-position: 4.0.0
+
+ vfile@6.0.3:
+ dependencies:
+ '@types/unist': 3.0.3
+ vfile-message: 4.0.3
+
+ vite@7.3.1(@types/node@25.5.0)(jiti@2.6.1)(lightningcss@1.32.0)(yaml@2.8.3):
+ dependencies:
+ esbuild: 0.27.4
+ fdir: 6.5.0(picomatch@4.0.3)
+ picomatch: 4.0.3
+ postcss: 8.5.8
+ rollup: 4.60.0
+ tinyglobby: 0.2.15
+ optionalDependencies:
+ '@types/node': 25.5.0
+ fsevents: 2.3.3
+ jiti: 2.6.1
+ lightningcss: 1.32.0
+ yaml: 2.8.3
+
+ vitefu@1.1.2(vite@7.3.1(@types/node@25.5.0)(jiti@2.6.1)(lightningcss@1.32.0)(yaml@2.8.3)):
+ optionalDependencies:
+ vite: 7.3.1(@types/node@25.5.0)(jiti@2.6.1)(lightningcss@1.32.0)(yaml@2.8.3)
+
+ vitest@4.1.1(@types/node@25.5.0)(@vitest/ui@4.1.1)(jsdom@29.0.1)(vite@7.3.1(@types/node@25.5.0)(jiti@2.6.1)(lightningcss@1.32.0)(yaml@2.8.3)):
+ dependencies:
+ '@vitest/expect': 4.1.1
+ '@vitest/mocker': 4.1.1(vite@7.3.1(@types/node@25.5.0)(jiti@2.6.1)(lightningcss@1.32.0)(yaml@2.8.3))
+ '@vitest/pretty-format': 4.1.1
+ '@vitest/runner': 4.1.1
+ '@vitest/snapshot': 4.1.1
+ '@vitest/spy': 4.1.1
+ '@vitest/utils': 4.1.1
+ es-module-lexer: 2.0.0
+ expect-type: 1.3.0
+ magic-string: 0.30.21
+ obug: 2.1.1
+ pathe: 2.0.3
+ picomatch: 4.0.3
+ std-env: 4.0.0
+ tinybench: 2.9.0
+ tinyexec: 1.0.4
+ tinyglobby: 0.2.15
+ tinyrainbow: 3.1.0
+ vite: 7.3.1(@types/node@25.5.0)(jiti@2.6.1)(lightningcss@1.32.0)(yaml@2.8.3)
+ why-is-node-running: 2.3.0
+ optionalDependencies:
+ '@types/node': 25.5.0
+ '@vitest/ui': 4.1.1(vitest@4.1.1)
+ jsdom: 29.0.1
+ transitivePeerDependencies:
+ - msw
+
+ volar-service-css@0.0.70(@volar/language-service@2.4.28):
+ dependencies:
+ vscode-css-languageservice: 6.3.10
+ vscode-languageserver-textdocument: 1.0.12
+ vscode-uri: 3.1.0
+ optionalDependencies:
+ '@volar/language-service': 2.4.28
+
+ volar-service-emmet@0.0.70(@volar/language-service@2.4.28):
+ dependencies:
+ '@emmetio/css-parser': 0.4.1
+ '@emmetio/html-matcher': 1.3.0
+ '@vscode/emmet-helper': 2.11.0
+ vscode-uri: 3.1.0
+ optionalDependencies:
+ '@volar/language-service': 2.4.28
+
+ volar-service-html@0.0.70(@volar/language-service@2.4.28):
+ dependencies:
+ vscode-html-languageservice: 5.6.2
+ vscode-languageserver-textdocument: 1.0.12
+ vscode-uri: 3.1.0
+ optionalDependencies:
+ '@volar/language-service': 2.4.28
+
+ volar-service-prettier@0.0.70(@volar/language-service@2.4.28)(prettier@3.8.1):
+ dependencies:
+ vscode-uri: 3.1.0
+ optionalDependencies:
+ '@volar/language-service': 2.4.28
+ prettier: 3.8.1
+
+ volar-service-typescript-twoslash-queries@0.0.70(@volar/language-service@2.4.28):
+ dependencies:
+ vscode-uri: 3.1.0
+ optionalDependencies:
+ '@volar/language-service': 2.4.28
+
+ volar-service-typescript@0.0.70(@volar/language-service@2.4.28):
+ dependencies:
+ path-browserify: 1.0.1
+ semver: 7.7.4
+ typescript-auto-import-cache: 0.3.6
+ vscode-languageserver-textdocument: 1.0.12
+ vscode-nls: 5.2.0
+ vscode-uri: 3.1.0
+ optionalDependencies:
+ '@volar/language-service': 2.4.28
+
+ volar-service-yaml@0.0.70(@volar/language-service@2.4.28):
+ dependencies:
+ vscode-uri: 3.1.0
+ yaml-language-server: 1.20.0
+ optionalDependencies:
+ '@volar/language-service': 2.4.28
+
+ vscode-css-languageservice@6.3.10:
+ dependencies:
+ '@vscode/l10n': 0.0.18
+ vscode-languageserver-textdocument: 1.0.12
+ vscode-languageserver-types: 3.17.5
+ vscode-uri: 3.1.0
+
+ vscode-html-languageservice@5.6.2:
+ dependencies:
+ '@vscode/l10n': 0.0.18
+ vscode-languageserver-textdocument: 1.0.12
+ vscode-languageserver-types: 3.17.5
+ vscode-uri: 3.1.0
+
+ vscode-json-languageservice@4.1.8:
+ dependencies:
+ jsonc-parser: 3.3.1
+ vscode-languageserver-textdocument: 1.0.12
+ vscode-languageserver-types: 3.17.5
+ vscode-nls: 5.2.0
+ vscode-uri: 3.1.0
+
+ vscode-jsonrpc@8.2.0: {}
+
+ vscode-languageserver-protocol@3.17.5:
+ dependencies:
+ vscode-jsonrpc: 8.2.0
+ vscode-languageserver-types: 3.17.5
+
+ vscode-languageserver-textdocument@1.0.12: {}
+
+ vscode-languageserver-types@3.17.5: {}
+
+ vscode-languageserver@9.0.1:
+ dependencies:
+ vscode-languageserver-protocol: 3.17.5
+
+ vscode-nls@5.2.0: {}
+
+ vscode-uri@3.1.0: {}
+
+ w3c-xmlserializer@5.0.0:
+ dependencies:
+ xml-name-validator: 5.0.0
+
+ web-namespaces@2.0.1: {}
+
+ webidl-conversions@8.0.1: {}
+
+ whatwg-encoding@3.1.1:
+ dependencies:
+ iconv-lite: 0.6.3
+
+ whatwg-mimetype@4.0.0: {}
+
+ whatwg-mimetype@5.0.0: {}
+
+ whatwg-url@16.0.1:
+ dependencies:
+ '@exodus/bytes': 1.15.0
+ tr46: 6.0.0
+ webidl-conversions: 8.0.1
+ transitivePeerDependencies:
+ - '@noble/hashes'
+
+ which-pm-runs@1.1.0: {}
+
+ why-is-node-running@2.3.0:
+ dependencies:
+ siginfo: 2.0.0
+ stackback: 0.0.2
+
+ wrap-ansi@7.0.0:
+ dependencies:
+ ansi-styles: 4.3.0
+ string-width: 4.2.3
+ strip-ansi: 6.0.1
+
+ wrappy@1.0.2: {}
+
+ xml-name-validator@5.0.0: {}
+
+ xml2js@0.5.0:
+ dependencies:
+ sax: 1.6.0
+ xmlbuilder: 11.0.1
+
+ xmlbuilder@11.0.1: {}
+
+ xmlchars@2.2.0: {}
+
+ xxhash-wasm@1.1.0: {}
+
+ y18n@5.0.8: {}
+
+ yallist@5.0.0: {}
+
+ yaml-language-server@1.20.0:
+ dependencies:
+ '@vscode/l10n': 0.0.18
+ ajv: 8.18.0
+ ajv-draft-04: 1.0.0(ajv@8.18.0)
+ prettier: 3.8.1
+ request-light: 0.5.8
+ vscode-json-languageservice: 4.1.8
+ vscode-languageserver: 9.0.1
+ vscode-languageserver-textdocument: 1.0.12
+ vscode-languageserver-types: 3.17.5
+ vscode-uri: 3.1.0
+ yaml: 2.7.1
+
+ yaml@2.7.1: {}
+
+ yaml@2.8.3: {}
+
+ yargs-parser@21.1.1: {}
+
+ yargs-parser@22.0.0: {}
+
+ yargs@17.7.2:
+ dependencies:
+ cliui: 8.0.1
+ escalade: 3.2.0
+ get-caller-file: 2.0.5
+ require-directory: 2.1.1
+ string-width: 4.2.3
+ y18n: 5.0.8
+ yargs-parser: 21.1.1
+
+ yauzl@2.10.0:
+ dependencies:
+ buffer-crc32: 0.2.13
+ fd-slicer: 1.1.0
+
+ yocto-queue@1.2.2: {}
+
+ zod@4.3.6: {}
+
+ zwitch@2.0.4: {}
diff --git a/prepare-json.js b/prepare-json.js
deleted file mode 100644
index 0461f014..00000000
--- a/prepare-json.js
+++ /dev/null
@@ -1,156 +0,0 @@
-const dotenv = require('dotenv').config()
-const colors = require("colors")
-const fs = require('fs')
-const { Events, Videos, Source } = require('metagroup-schema-tools')
-const moment = require('moment')
-const SOURCE_JSON = process.env.VIGOTECH_MEMBERS_SOURCE_FILE
-const GENERATED_JSON = 'static/vigotech-generated.json'
-const JSON_SCHEMA = 'static/vigotech-schema.json'
-
-
-
-
-function eventDate(date) {
- return moment(date).format('dddd, D MMMM YYYY HH:mm')
-}
-
-function getNextEvents(data) {
-
- const eventEmitter = Events.getEventsEmitter()
-
- eventEmitter.on('getNextFromSourceInit', (source, options) => {
- console.log(` · Getting upcoming events json for ${colors.green(options.member.name)} from ${colors.underline(source.type)}`);
- })
-
- eventEmitter.on('getNextFromSourceCompleted', (nextEvents, options) => {
- if (nextEvents.length === 0) {
- console.log(` ${colors.yellow(`No upcoming events found`)}`)
- } else {
- if (nextEvents.length === undefined) {
- nextEvents = [nextEvents]
- }
-
- const nextEvent = nextEvents[0]
- console.log(` ${colors.cyan(`Upcoming event found:`)} ${colors.blue(`${colors.bold(`${nextEvent.title}`)} ${eventDate(nextEvent.date)}`)}`)
- }
- console.log();
- })
-
-
- // Get root group next events
- const rootNextEvents = Events.getGroupNextEvents(data.events, {
- eventbriteToken: process.env.EVENTBRITE_OAUTH_TOKEN,
- member: data
- })
- data.nextEvent = rootNextEvents[0]
-
-
- // Get members next events
- for(let memberKey in data.members) {
- const member = data.members[memberKey]
- const membersNextEvents = Events.getGroupNextEvents(member.events, {
- eventbriteToken: process.env.EVENTBRITE_OAUTH_TOKEN,
- member: member
- })
-
- data.members[memberKey].nextEvent = membersNextEvents[0]
-
- }
-
- return data
-}
-
-
-async function getMembersVideos(membersData) {
-
- const eventEmitter = Videos.getEventsEmitter()
-
- eventEmitter.on('getVideosFromSourceInit', (source, options) => {
- console.log(` · Getting member videos for ${colors.green(options.member.name)} from ${colors.underline(source.type)}`);
- })
-
- eventEmitter.on('getVideosFromSourceCompleted', (videos, options) => {
- if (videos.length == 0) {
- console.log(` ${colors.yellow(`No videos found`)}`)
- }
- else {
- console.log(` ${colors.cyan(`Imported ${videos.length} videos`)}`)
- }
- console.log();
- })
-
-
- // Get members videos
- for(let memberKey in data.members) {
- const member = data.members[memberKey]
- data.members[memberKey].videoList = await Videos.getGroupVideos(member.videos, 6, {
- youtubeApiKey: process.env.YOUTUBE_API_KEY,
- member: member
- })
- }
-
- return data
-}
-
-function saveJsonFile(data) {
- fs.writeFileSync(GENERATED_JSON, JSON.stringify(data));
- console.log(` ${colors.inverse(`Saving ${colors.yellow(`${GENERATED_JSON}`)}`)}`);
-}
-
-
-
-
-
-
-
-
-
-// Read and parse source data
-console.log(`${colors.inverse("Getting vigotech.json file")}`);
-console.log(` Getting members json from ${colors.underline(SOURCE_JSON)}`)
-let data = {}
-try {
- const dataRaw = fs.readFileSync(SOURCE_JSON, 'utf8')
- data = JSON.parse(dataRaw)
-} catch(e) {
- console.log(`${colors.red.inverse(e)}`);
- process.exit(1)
-}
-
-// Validate data schema
-console.log(`${colors.inverse("Validate vigotech.json file")}`);
-console.log(` Getting json schema from ${colors.underline(JSON_SCHEMA)}`);
-let schema = {}
-try {
- const schemaRaw = fs.readFileSync(JSON_SCHEMA, 'utf8')
- schema = JSON.parse(schemaRaw)
-} catch(e) {
- console.log(`${colors.red.inverse(e)}`);
- process.exit(1)
-}
-const validationResult = Source.validate(data, schema)
-
-if (validationResult.errors.length > 0) {
- console.log(`${colors.red.inverse('Error validating source data')}`);
- console.log(typeof validationResult.errors)
- validationResult.errors.forEach( (error) => {
- console.log(` ${colors.red(error.property + ' ' + error.message)}`)
- console.log(error.instance)
- })
- process.exit(1);
-}
-console.log(` ${colors.green.inverse('OK')}`);
-
-// Import events
-console.log(`${colors.inverse("Preparing json files")}`);
-console.log(`${colors.bold(" Import next events")}`);
-data = getNextEvents(data)
-console.log();
-console.log();
-
-//Import videos
-console.log(`${colors.bold(" Import videos")}`);
-getMembersVideos(data)
- .then(data => {
- saveJsonFile(data)
- })
diff --git a/static/CNAME b/public/CNAME
similarity index 100%
rename from static/CNAME
rename to public/CNAME
diff --git a/static/favicon.ico b/public/favicon.ico
similarity index 100%
rename from static/favicon.ico
rename to public/favicon.ico
diff --git a/public/favicon.svg b/public/favicon.svg
new file mode 100644
index 00000000..f157bd1c
--- /dev/null
+++ b/public/favicon.svg
@@ -0,0 +1,9 @@
+
+
+
+
diff --git a/public/fonts/instrument-serif-latin-italic.woff2 b/public/fonts/instrument-serif-latin-italic.woff2
new file mode 100644
index 00000000..197abca2
Binary files /dev/null and b/public/fonts/instrument-serif-latin-italic.woff2 differ
diff --git a/public/fonts/instrument-serif-latin.woff2 b/public/fonts/instrument-serif-latin.woff2
new file mode 100644
index 00000000..0ad69719
Binary files /dev/null and b/public/fonts/instrument-serif-latin.woff2 differ
diff --git a/public/fonts/inter-latin.woff2 b/public/fonts/inter-latin.woff2
new file mode 100644
index 00000000..d15208de
Binary files /dev/null and b/public/fonts/inter-latin.woff2 differ
diff --git a/public/fonts/space-grotesk-latin.woff2 b/public/fonts/space-grotesk-latin.woff2
new file mode 100644
index 00000000..0f3474ee
Binary files /dev/null and b/public/fonts/space-grotesk-latin.woff2 differ
diff --git a/static/friends-schema.json b/public/friends-schema.json
similarity index 88%
rename from static/friends-schema.json
rename to public/friends-schema.json
index e2ea6518..8811e228 100644
--- a/static/friends-schema.json
+++ b/public/friends-schema.json
@@ -4,11 +4,7 @@
"description": "",
"$schema": "http://json-schema.org/draft-04/schema#",
"additionalProperties": false,
- "required": [
- "name",
- "logo",
- "link"
- ],
+ "required": ["name", "logo", "link"],
"properties": {
"name": {
"type": "string",
diff --git a/static/friends.json b/public/friends.json
similarity index 100%
rename from static/friends.json
rename to public/friends.json
diff --git a/static/friends/compostelatech.jpg b/public/friends/compostelatech.jpg
similarity index 100%
rename from static/friends/compostelatech.jpg
rename to public/friends/compostelatech.jpg
diff --git a/static/friends/copenhagen.jpg b/public/friends/copenhagen.jpg
similarity index 100%
rename from static/friends/copenhagen.jpg
rename to public/friends/copenhagen.jpg
diff --git a/static/friends/madridtech.jpg b/public/friends/madridtech.jpg
similarity index 100%
rename from static/friends/madridtech.jpg
rename to public/friends/madridtech.jpg
diff --git a/static/friends/riojatech.png b/public/friends/riojatech.png
similarity index 100%
rename from static/friends/riojatech.png
rename to public/friends/riojatech.png
diff --git a/static/images/agile_vigo.jpg b/public/images/groups/agile_vigo.jpg
similarity index 100%
rename from static/images/agile_vigo.jpg
rename to public/images/groups/agile_vigo.jpg
diff --git a/static/images/aindustriosa.png b/public/images/groups/aindustriosa.png
similarity index 100%
rename from static/images/aindustriosa.png
rename to public/images/groups/aindustriosa.png
diff --git a/static/images/blockchaingal.png b/public/images/groups/blockchaingal.png
similarity index 100%
rename from static/images/blockchaingal.png
rename to public/images/groups/blockchaingal.png
diff --git a/static/images/craftersVigo.png b/public/images/groups/craftersVigo.png
similarity index 100%
rename from static/images/craftersVigo.png
rename to public/images/groups/craftersVigo.png
diff --git a/static/images/galpon.png b/public/images/groups/galpon.png
similarity index 100%
rename from static/images/galpon.png
rename to public/images/groups/galpon.png
diff --git a/static/images/galstech.png b/public/images/groups/galstech.png
similarity index 100%
rename from static/images/galstech.png
rename to public/images/groups/galstech.png
diff --git a/static/images/gdg_vigo.png b/public/images/groups/gdg_vigo.png
similarity index 100%
rename from static/images/gdg_vigo.png
rename to public/images/groups/gdg_vigo.png
diff --git a/static/images/joomla_vigo.png b/public/images/groups/joomla_vigo.png
similarity index 100%
rename from static/images/joomla_vigo.png
rename to public/images/groups/joomla_vigo.png
diff --git a/static/images/jsvigo.png b/public/images/groups/jsvigo.png
similarity index 100%
rename from static/images/jsvigo.png
rename to public/images/groups/jsvigo.png
diff --git a/static/images/php_vigo.jpg b/public/images/groups/php_vigo.jpg
similarity index 100%
rename from static/images/php_vigo.jpg
rename to public/images/groups/php_vigo.jpg
diff --git a/static/images/python_vigo.png b/public/images/groups/python_vigo.png
similarity index 100%
rename from static/images/python_vigo.png
rename to public/images/groups/python_vigo.png
diff --git a/static/images/seogalicia.png b/public/images/groups/seogalicia.png
similarity index 100%
rename from static/images/seogalicia.png
rename to public/images/groups/seogalicia.png
diff --git a/static/images/sysadmin_galicia.jpg b/public/images/groups/sysadmin_galicia.jpg
similarity index 100%
rename from static/images/sysadmin_galicia.jpg
rename to public/images/groups/sysadmin_galicia.jpg
diff --git a/static/images/ux_gal.jpg b/public/images/groups/ux_gal.jpg
similarity index 100%
rename from static/images/ux_gal.jpg
rename to public/images/groups/ux_gal.jpg
diff --git a/static/images/vigoadg.jpg b/public/images/groups/vigoadg.jpg
similarity index 100%
rename from static/images/vigoadg.jpg
rename to public/images/groups/vigoadg.jpg
diff --git a/static/images/vigobrain.png b/public/images/groups/vigobrain.png
similarity index 100%
rename from static/images/vigobrain.png
rename to public/images/groups/vigobrain.png
diff --git a/static/images/vigojug.jpg b/public/images/groups/vigojug.jpg
similarity index 100%
rename from static/images/vigojug.jpg
rename to public/images/groups/vigojug.jpg
diff --git a/static/images/vigowordpress.png b/public/images/groups/vigowordpress.png
similarity index 100%
rename from static/images/vigowordpress.png
rename to public/images/groups/vigowordpress.png
diff --git a/static/images/wordpress-pontevedra.png b/public/images/groups/wordpress-pontevedra.png
similarity index 100%
rename from static/images/wordpress-pontevedra.png
rename to public/images/groups/wordpress-pontevedra.png
diff --git a/static/slack.png b/public/slack.png
similarity index 100%
rename from static/slack.png
rename to public/slack.png
diff --git a/static/vigotech-events-schema.json b/public/vigotech-events-schema.json
similarity index 91%
rename from static/vigotech-events-schema.json
rename to public/vigotech-events-schema.json
index bae89c75..bd0192c0 100644
--- a/static/vigotech-events-schema.json
+++ b/public/vigotech-events-schema.json
@@ -4,11 +4,7 @@
"description": "",
"$schema": "http://json-schema.org/draft-04/schema#",
"additionalProperties": false,
- "required": [
- "title",
- "date",
- "url"
- ],
+ "required": ["title", "date", "url"],
"properties": {
"title": {
"type": "string",
diff --git a/public/vigotech-generated.json b/public/vigotech-generated.json
new file mode 100644
index 00000000..04bc7b83
--- /dev/null
+++ b/public/vigotech-generated.json
@@ -0,0 +1,5547 @@
+{
+ "name": "VigoTech Alliance",
+ "logo": "https://github.com/VigoTech/Design-elements/blob/master/01%20IDENTIDAD%20CORPORATIVA/01%20EXPORT/PNG/Logo%20VIGOTECH_avatar_redondo.png?raw=true",
+ "sticker": "http://hexb.in/hexagons/vigotech.png",
+ "links": {
+ "web": "https://vigotech.org/",
+ "twitter": "http://twitter.com/vigotechallianc",
+ "mail": "alliance@vigotech.org",
+ "github": "https://github.com/VigoTech"
+ },
+ "events": {
+ "type": "eventbrite",
+ "eventbriteid": "17365087639"
+ },
+ "members": {
+ "agilevigo": {
+ "name": "Agile Vigo",
+ "logo": "https://vigotech.org/images/agile_vigo.jpg",
+ "links": {
+ "twitter": "https://twitter.com/agilevigo",
+ "meetup": "https://www.meetup.com/es-ES/agile-vigo/",
+ "github": "https://github.com/agileVigo"
+ },
+ "events": [
+ {
+ "type": "meetup",
+ "meetupid": "agile-vigo"
+ }
+ ],
+ "inactive": true,
+ "nextEvent": {
+ "title": "Vibe Coding Luxembourg: Build a Real App in 60 Minutes with AI",
+ "date": 1774544400000,
+ "url": "https://www.meetup.com/luxembourg-vibe-coding-meetup-group/events/313651478/",
+ "location": "Online event"
+ },
+ "videoList": [],
+ "eventList": []
+ },
+ "aindustriosa": {
+ "name": "A Industriosa",
+ "logo": "https://vigotech.org/images/aindustriosa.png",
+ "links": {
+ "web": "https://aindustriosa.org/",
+ "twitter": "https://twitter.com/aindustriosa",
+ "meetup": "https://www.meetup.com/es-ES/AIndustriosa/",
+ "youtube": "https://www.youtube.com/channel/UC9DPKfcLiNd7SEU-QLlIG7A"
+ },
+ "events": {
+ "type": "meetup",
+ "meetupid": "AIndustriosa"
+ },
+ "videos": [
+ {
+ "type": "youtube",
+ "channel_id": "UC9DPKfcLiNd7SEU-QLlIG7A"
+ }
+ ],
+ "nextEvent": null,
+ "videoList": [
+ {
+ "player": "youtube",
+ "id": "9U0djWiKyGA",
+ "title": "20250322 - Galegos na FOSDEM - David de la Iglesia",
+ "pubDate": 1743146051000,
+ "thumbnails": {
+ "default": {
+ "url": "https://i.ytimg.com/vi/9U0djWiKyGA/default.jpg",
+ "width": 120,
+ "height": 90
+ },
+ "medium": {
+ "url": "https://i.ytimg.com/vi/9U0djWiKyGA/mqdefault.jpg",
+ "width": 320,
+ "height": 180
+ },
+ "high": {
+ "url": "https://i.ytimg.com/vi/9U0djWiKyGA/hqdefault.jpg",
+ "width": 480,
+ "height": 360
+ }
+ }
+ },
+ {
+ "player": "youtube",
+ "id": "33Xt39a_cEc",
+ "title": "20250322 - Galegos na FOSDEM - José María Casanova",
+ "pubDate": 1743146003000,
+ "thumbnails": {
+ "default": {
+ "url": "https://i.ytimg.com/vi/33Xt39a_cEc/default.jpg",
+ "width": 120,
+ "height": 90
+ },
+ "medium": {
+ "url": "https://i.ytimg.com/vi/33Xt39a_cEc/mqdefault.jpg",
+ "width": 320,
+ "height": 180
+ },
+ "high": {
+ "url": "https://i.ytimg.com/vi/33Xt39a_cEc/hqdefault.jpg",
+ "width": 480,
+ "height": 360
+ }
+ }
+ },
+ {
+ "player": "youtube",
+ "id": "RMtWdPJaHeU",
+ "title": "20250322 - Galegos na FOSDEM - Xabier Crespo",
+ "pubDate": 1743145983000,
+ "thumbnails": {
+ "default": {
+ "url": "https://i.ytimg.com/vi/RMtWdPJaHeU/default.jpg",
+ "width": 120,
+ "height": 90
+ },
+ "medium": {
+ "url": "https://i.ytimg.com/vi/RMtWdPJaHeU/mqdefault.jpg",
+ "width": 320,
+ "height": 180
+ },
+ "high": {
+ "url": "https://i.ytimg.com/vi/RMtWdPJaHeU/hqdefault.jpg",
+ "width": 480,
+ "height": 360
+ }
+ }
+ },
+ {
+ "player": "youtube",
+ "id": "DnTVDXVMLqY",
+ "title": "20250322 - Galegos na FOSDEM - Sam Thursfield",
+ "pubDate": 1743145954000,
+ "thumbnails": {
+ "default": {
+ "url": "https://i.ytimg.com/vi/DnTVDXVMLqY/default.jpg",
+ "width": 120,
+ "height": 90
+ },
+ "medium": {
+ "url": "https://i.ytimg.com/vi/DnTVDXVMLqY/mqdefault.jpg",
+ "width": 320,
+ "height": 180
+ },
+ "high": {
+ "url": "https://i.ytimg.com/vi/DnTVDXVMLqY/hqdefault.jpg",
+ "width": 480,
+ "height": 360
+ }
+ }
+ },
+ {
+ "player": "youtube",
+ "id": "Z1Q7z6Whz8A",
+ "title": "20250322 - Galegos na FOSDEM - Santiago Saavedra",
+ "pubDate": 1743145846000,
+ "thumbnails": {
+ "default": {
+ "url": "https://i.ytimg.com/vi/Z1Q7z6Whz8A/default.jpg",
+ "width": 120,
+ "height": 90
+ },
+ "medium": {
+ "url": "https://i.ytimg.com/vi/Z1Q7z6Whz8A/mqdefault.jpg",
+ "width": 320,
+ "height": 180
+ },
+ "high": {
+ "url": "https://i.ytimg.com/vi/Z1Q7z6Whz8A/hqdefault.jpg",
+ "width": 480,
+ "height": 360
+ }
+ }
+ },
+ {
+ "player": "youtube",
+ "id": "PJ5mEkki06g",
+ "title": "20240313 - Solana: unha guía para principiantes, por José Corral",
+ "pubDate": 1718384640000,
+ "thumbnails": {
+ "default": {
+ "url": "https://i.ytimg.com/vi/PJ5mEkki06g/default.jpg",
+ "width": 120,
+ "height": 90
+ },
+ "medium": {
+ "url": "https://i.ytimg.com/vi/PJ5mEkki06g/mqdefault.jpg",
+ "width": 320,
+ "height": 180
+ },
+ "high": {
+ "url": "https://i.ytimg.com/vi/PJ5mEkki06g/hqdefault.jpg",
+ "width": 480,
+ "height": 360
+ }
+ }
+ },
+ {
+ "player": "youtube",
+ "id": "w40F9WOatq4",
+ "title": "20240613 - Descobre o poder da programación funcional a través de OCaml, por Jose Castillo",
+ "pubDate": 1718381629000,
+ "thumbnails": {
+ "default": {
+ "url": "https://i.ytimg.com/vi/w40F9WOatq4/default.jpg",
+ "width": 120,
+ "height": 90
+ },
+ "medium": {
+ "url": "https://i.ytimg.com/vi/w40F9WOatq4/mqdefault.jpg",
+ "width": 320,
+ "height": 180
+ },
+ "high": {
+ "url": "https://i.ytimg.com/vi/w40F9WOatq4/hqdefault.jpg",
+ "width": 480,
+ "height": 360
+ }
+ }
+ },
+ {
+ "player": "youtube",
+ "id": "P4Jz9ramhsE",
+ "title": "Introducción a Mesa, por Igalia 28/10/2023",
+ "pubDate": 1698684367000,
+ "thumbnails": {
+ "default": {
+ "url": "https://i.ytimg.com/vi/P4Jz9ramhsE/default.jpg",
+ "width": 120,
+ "height": 90
+ },
+ "medium": {
+ "url": "https://i.ytimg.com/vi/P4Jz9ramhsE/mqdefault.jpg",
+ "width": 320,
+ "height": 180
+ },
+ "high": {
+ "url": "https://i.ytimg.com/vi/P4Jz9ramhsE/hqdefault.jpg",
+ "width": 480,
+ "height": 360
+ }
+ }
+ },
+ {
+ "player": "youtube",
+ "id": "Ozy-ptJtpXU",
+ "title": "20230624 - Tecnoloxía Aplicada á Investigación en Ocupación, Igualdade e Saúde",
+ "pubDate": 1688114733000,
+ "thumbnails": {
+ "default": {
+ "url": "https://i.ytimg.com/vi/Ozy-ptJtpXU/default.jpg",
+ "width": 120,
+ "height": 90
+ },
+ "medium": {
+ "url": "https://i.ytimg.com/vi/Ozy-ptJtpXU/mqdefault.jpg",
+ "width": 320,
+ "height": 180
+ },
+ "high": {
+ "url": "https://i.ytimg.com/vi/Ozy-ptJtpXU/hqdefault.jpg",
+ "width": 480,
+ "height": 360
+ }
+ }
+ },
+ {
+ "player": "youtube",
+ "id": "nkEzTnaT9g4",
+ "title": "20230626 - Robótica de competición: OPRobots, moita, moita proba e erro",
+ "pubDate": 1688074416000,
+ "thumbnails": {
+ "default": {
+ "url": "https://i.ytimg.com/vi/nkEzTnaT9g4/default.jpg",
+ "width": 120,
+ "height": 90
+ },
+ "medium": {
+ "url": "https://i.ytimg.com/vi/nkEzTnaT9g4/mqdefault.jpg",
+ "width": 320,
+ "height": 180
+ },
+ "high": {
+ "url": "https://i.ytimg.com/vi/nkEzTnaT9g4/hqdefault.jpg",
+ "width": 480,
+ "height": 360
+ }
+ }
+ },
+ {
+ "player": "youtube",
+ "id": "E-3KOZCmwBU",
+ "title": "20230511 - Engineering Manager: Beyond Leadership",
+ "pubDate": 1683929679000,
+ "thumbnails": {
+ "default": {
+ "url": "https://i.ytimg.com/vi/E-3KOZCmwBU/default.jpg",
+ "width": 120,
+ "height": 90
+ },
+ "medium": {
+ "url": "https://i.ytimg.com/vi/E-3KOZCmwBU/mqdefault.jpg",
+ "width": 320,
+ "height": 180
+ },
+ "high": {
+ "url": "https://i.ytimg.com/vi/E-3KOZCmwBU/hqdefault.jpg",
+ "width": 480,
+ "height": 360
+ }
+ }
+ },
+ {
+ "player": "youtube",
+ "id": "9p2kho8RJW0",
+ "title": "20230414 - Rural Hackers",
+ "pubDate": 1681596391000,
+ "thumbnails": {
+ "default": {
+ "url": "https://i.ytimg.com/vi/9p2kho8RJW0/default.jpg",
+ "width": 120,
+ "height": 90
+ },
+ "medium": {
+ "url": "https://i.ytimg.com/vi/9p2kho8RJW0/mqdefault.jpg",
+ "width": 320,
+ "height": 180
+ },
+ "high": {
+ "url": "https://i.ytimg.com/vi/9p2kho8RJW0/hqdefault.jpg",
+ "width": 480,
+ "height": 360
+ }
+ }
+ },
+ {
+ "player": "youtube",
+ "id": "nkcYW4GnRmg",
+ "title": "20220924 - Como (no) fabricar Motores Eléctricos",
+ "pubDate": 1664205122000,
+ "thumbnails": {
+ "default": {
+ "url": "https://i.ytimg.com/vi/nkcYW4GnRmg/default.jpg",
+ "width": 120,
+ "height": 90
+ },
+ "medium": {
+ "url": "https://i.ytimg.com/vi/nkcYW4GnRmg/mqdefault.jpg",
+ "width": 320,
+ "height": 180
+ },
+ "high": {
+ "url": "https://i.ytimg.com/vi/nkcYW4GnRmg/hqdefault.jpg",
+ "width": 480,
+ "height": 360
+ }
+ }
+ },
+ {
+ "player": "youtube",
+ "id": "JgK0oBo0a7E",
+ "title": "20220709 - Autoconsumo Solar",
+ "pubDate": 1657412138000,
+ "thumbnails": {
+ "default": {
+ "url": "https://i.ytimg.com/vi/JgK0oBo0a7E/default.jpg",
+ "width": 120,
+ "height": 90
+ },
+ "medium": {
+ "url": "https://i.ytimg.com/vi/JgK0oBo0a7E/mqdefault.jpg",
+ "width": 320,
+ "height": 180
+ },
+ "high": {
+ "url": "https://i.ytimg.com/vi/JgK0oBo0a7E/hqdefault.jpg",
+ "width": 480,
+ "height": 360
+ }
+ }
+ },
+ {
+ "player": "youtube",
+ "id": "STF14PwIMP4",
+ "title": "CES UVigo: Fabricación de barcos solares tripulados para competición",
+ "pubDate": 1648707933000,
+ "thumbnails": {
+ "default": {
+ "url": "https://i.ytimg.com/vi/STF14PwIMP4/default.jpg",
+ "width": 120,
+ "height": 90
+ },
+ "medium": {
+ "url": "https://i.ytimg.com/vi/STF14PwIMP4/mqdefault.jpg",
+ "width": 320,
+ "height": 180
+ },
+ "high": {
+ "url": "https://i.ytimg.com/vi/STF14PwIMP4/hqdefault.jpg",
+ "width": 480,
+ "height": 360
+ }
+ }
+ },
+ {
+ "player": "youtube",
+ "id": "R_K0saprZPw",
+ "title": "Reciclaxe de plásticos a pequeña escala con máquinas open source",
+ "pubDate": null,
+ "thumbnails": {
+ "default": {
+ "url": "https://i.ytimg.com/vi/R_K0saprZPw/hqdefault.jpg?sqp=-oaymwEbCKgBEF5IVfKriqkDDggBFQAAiEIYAXABwAEG&rs=AOn4CLB4mx6Wdt66qeQFuZiV4Ko8RGuy8Q",
+ "width": 168,
+ "height": 94
+ },
+ "medium": {
+ "url": "https://i.ytimg.com/vi/R_K0saprZPw/hqdefault.jpg?sqp=-oaymwEbCMQBEG5IVfKriqkDDggBFQAAiEIYAXABwAEG&rs=AOn4CLCgUOMIkRR9rOmX-Fl7U-BVkn4YOg",
+ "width": 196,
+ "height": 110
+ },
+ "high": {
+ "url": "https://i.ytimg.com/vi/R_K0saprZPw/hqdefault.jpg?sqp=-oaymwEcCPYBEIoBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==&rs=AOn4CLCzpdNZXr7a0gudbcC7qu0gQz6t7g",
+ "width": 246,
+ "height": 138
+ },
+ "standard": {
+ "url": "https://i.ytimg.com/vi/R_K0saprZPw/hqdefault.jpg?sqp=-oaymwEcCNACELwBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==&rs=AOn4CLB4uKPyOSAoKPrr42UhUaR_6iZ6WA",
+ "width": 336,
+ "height": 188
+ }
+ }
+ },
+ {
+ "player": "youtube",
+ "id": "50TrtscnUis",
+ "title": "20210227 - Ultracasa 3000",
+ "pubDate": null,
+ "thumbnails": {
+ "default": {
+ "url": "https://i.ytimg.com/vi/50TrtscnUis/hqdefault.jpg?sqp=-oaymwEbCKgBEF5IVfKriqkDDggBFQAAiEIYAXABwAEG&rs=AOn4CLCqACfzWJPeo6fZw308LXFSTUqI8w",
+ "width": 168,
+ "height": 94
+ },
+ "medium": {
+ "url": "https://i.ytimg.com/vi/50TrtscnUis/hqdefault.jpg?sqp=-oaymwEbCMQBEG5IVfKriqkDDggBFQAAiEIYAXABwAEG&rs=AOn4CLDsregahFEzGtecxkxAHmYetWe8iw",
+ "width": 196,
+ "height": 110
+ },
+ "high": {
+ "url": "https://i.ytimg.com/vi/50TrtscnUis/hqdefault.jpg?sqp=-oaymwEcCPYBEIoBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==&rs=AOn4CLBAqYG3bOacuxrF9yvoIiImIEqTVw",
+ "width": 246,
+ "height": 138
+ },
+ "standard": {
+ "url": "https://i.ytimg.com/vi/50TrtscnUis/hqdefault.jpg?sqp=-oaymwEcCNACELwBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==&rs=AOn4CLB8S3u6LnzGnDm7MQcvlcoN7FUCvg",
+ "width": 336,
+ "height": 188
+ }
+ }
+ },
+ {
+ "player": "youtube",
+ "id": "bmMG6O0I4eI",
+ "title": "20200801 - [LIVE] - Hackeando mi robot aspirador",
+ "pubDate": null,
+ "thumbnails": {
+ "default": {
+ "url": "https://i.ytimg.com/vi/bmMG6O0I4eI/hqdefault.jpg?sqp=-oaymwEbCKgBEF5IVfKriqkDDggBFQAAiEIYAXABwAEG&rs=AOn4CLBisZ7qcyh5qle0Dp2hmskz_rmDUQ",
+ "width": 168,
+ "height": 94
+ },
+ "medium": {
+ "url": "https://i.ytimg.com/vi/bmMG6O0I4eI/hqdefault.jpg?sqp=-oaymwEbCMQBEG5IVfKriqkDDggBFQAAiEIYAXABwAEG&rs=AOn4CLAG82IyCNXZyZszN1A0W3gLzoc9Tg",
+ "width": 196,
+ "height": 110
+ },
+ "high": {
+ "url": "https://i.ytimg.com/vi/bmMG6O0I4eI/hqdefault.jpg?sqp=-oaymwEcCPYBEIoBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==&rs=AOn4CLBXWLavgdc6QZvHe4mH4jE0qOYJJw",
+ "width": 246,
+ "height": 138
+ },
+ "standard": {
+ "url": "https://i.ytimg.com/vi/bmMG6O0I4eI/hqdefault.jpg?sqp=-oaymwEcCNACELwBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==&rs=AOn4CLBp5SdOh3_cKYYGqZkRs-DlI7hbjw",
+ "width": 336,
+ "height": 188
+ }
+ }
+ },
+ {
+ "player": "youtube",
+ "id": "tNMsRnwnpYw",
+ "title": "20200424 - [LIVE] - Open Research Rocketry",
+ "pubDate": null,
+ "thumbnails": {
+ "default": {
+ "url": "https://i.ytimg.com/vi/tNMsRnwnpYw/hqdefault.jpg?sqp=-oaymwEbCKgBEF5IVfKriqkDDggBFQAAiEIYAXABwAEG&rs=AOn4CLDXqNT5RJ2Q5aLJKCKzvFww4zM0rw",
+ "width": 168,
+ "height": 94
+ },
+ "medium": {
+ "url": "https://i.ytimg.com/vi/tNMsRnwnpYw/hqdefault.jpg?sqp=-oaymwEbCMQBEG5IVfKriqkDDggBFQAAiEIYAXABwAEG&rs=AOn4CLCqUQXmbqi3LTPYqCbz-Dm9uUBXMQ",
+ "width": 196,
+ "height": 110
+ },
+ "high": {
+ "url": "https://i.ytimg.com/vi/tNMsRnwnpYw/hqdefault.jpg?sqp=-oaymwEcCPYBEIoBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==&rs=AOn4CLCsktKWwrn3ueXAG-N5JXlzWgDltg",
+ "width": 246,
+ "height": 138
+ },
+ "standard": {
+ "url": "https://i.ytimg.com/vi/tNMsRnwnpYw/hqdefault.jpg?sqp=-oaymwEcCNACELwBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==&rs=AOn4CLDRgqTJadY_1yBdDFHx-Bt0pEfvBg",
+ "width": 336,
+ "height": 188
+ }
+ }
+ },
+ {
+ "player": "youtube",
+ "id": "GtqKbhFsR_g",
+ "title": "20200406 - Regata Solar - Curso Electrónica e propulsión",
+ "pubDate": null,
+ "thumbnails": {
+ "default": {
+ "url": "https://i.ytimg.com/vi/GtqKbhFsR_g/hqdefault.jpg?sqp=-oaymwEbCKgBEF5IVfKriqkDDggBFQAAiEIYAXABwAEG&rs=AOn4CLDgSxaWpiocSCYFevmMpFQ9hC8AQA",
+ "width": 168,
+ "height": 94
+ },
+ "medium": {
+ "url": "https://i.ytimg.com/vi/GtqKbhFsR_g/hqdefault.jpg?sqp=-oaymwEbCMQBEG5IVfKriqkDDggBFQAAiEIYAXABwAEG&rs=AOn4CLB2bQtyeWSNiJSeCxeGQb8c8Zg50w",
+ "width": 196,
+ "height": 110
+ },
+ "high": {
+ "url": "https://i.ytimg.com/vi/GtqKbhFsR_g/hqdefault.jpg?sqp=-oaymwEcCPYBEIoBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==&rs=AOn4CLCUXqlvf8IMo_L4faAtFwxJMK7yvw",
+ "width": 246,
+ "height": 138
+ },
+ "standard": {
+ "url": "https://i.ytimg.com/vi/GtqKbhFsR_g/hqdefault.jpg?sqp=-oaymwEcCNACELwBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==&rs=AOn4CLBzvo_9B22hlAxtsqoIDcqzcfM79g",
+ "width": 336,
+ "height": 188
+ }
+ }
+ },
+ {
+ "player": "youtube",
+ "id": "FuQ5glFzmJA",
+ "title": "20200408 - [LIVE] - Regata Solar - Curso Radiocontrol e Telemetría",
+ "pubDate": null,
+ "thumbnails": {
+ "default": {
+ "url": "https://i.ytimg.com/vi/FuQ5glFzmJA/hqdefault.jpg?sqp=-oaymwEbCKgBEF5IVfKriqkDDggBFQAAiEIYAXABwAEG&rs=AOn4CLC2kumNmmVNIcRtOlI4jyRJRy-c8w",
+ "width": 168,
+ "height": 94
+ },
+ "medium": {
+ "url": "https://i.ytimg.com/vi/FuQ5glFzmJA/hqdefault.jpg?sqp=-oaymwEbCMQBEG5IVfKriqkDDggBFQAAiEIYAXABwAEG&rs=AOn4CLD_k3aeZ0HV8Hk_aF9yxr2P6Oza8w",
+ "width": 196,
+ "height": 110
+ },
+ "high": {
+ "url": "https://i.ytimg.com/vi/FuQ5glFzmJA/hqdefault.jpg?sqp=-oaymwEcCPYBEIoBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==&rs=AOn4CLBPN5RoMszDGnx7rsELDS2D3kYalQ",
+ "width": 246,
+ "height": 138
+ },
+ "standard": {
+ "url": "https://i.ytimg.com/vi/FuQ5glFzmJA/hqdefault.jpg?sqp=-oaymwEcCNACELwBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==&rs=AOn4CLCG2hFvzBi8NYgv9x3GOHZR4gm8Bg",
+ "width": 336,
+ "height": 188
+ }
+ }
+ },
+ {
+ "player": "youtube",
+ "id": "FckZbnkM1hU",
+ "title": "Regata Solar - [LIVE] - Curso Electrónica e propulsión",
+ "pubDate": null,
+ "thumbnails": {
+ "default": {
+ "url": "https://i.ytimg.com/vi/FckZbnkM1hU/hqdefault.jpg?sqp=-oaymwEbCKgBEF5IVfKriqkDDggBFQAAiEIYAXABwAEG&rs=AOn4CLAaPaiCPGCOQFSUtCmV6UgAy5qU-g",
+ "width": 168,
+ "height": 94
+ },
+ "medium": {
+ "url": "https://i.ytimg.com/vi/FckZbnkM1hU/hqdefault.jpg?sqp=-oaymwEbCMQBEG5IVfKriqkDDggBFQAAiEIYAXABwAEG&rs=AOn4CLCkqPT_nUySEBYCxJUD9MSvtbCAew",
+ "width": 196,
+ "height": 110
+ },
+ "high": {
+ "url": "https://i.ytimg.com/vi/FckZbnkM1hU/hqdefault.jpg?sqp=-oaymwEcCPYBEIoBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==&rs=AOn4CLCEohmisHWnOO9-dZ5loKHsUDs2cg",
+ "width": 246,
+ "height": 138
+ },
+ "standard": {
+ "url": "https://i.ytimg.com/vi/FckZbnkM1hU/hqdefault.jpg?sqp=-oaymwEcCNACELwBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==&rs=AOn4CLDLNvoQ9CYnmpw4NaUhFSq7LDP2Pg",
+ "width": 336,
+ "height": 188
+ }
+ }
+ },
+ {
+ "player": "youtube",
+ "id": "VynI1x3QGI0",
+ "title": "20200319 - [LIVE] - Introducción a Lora e LoraWAN",
+ "pubDate": null,
+ "thumbnails": {
+ "default": {
+ "url": "https://i.ytimg.com/vi/VynI1x3QGI0/hqdefault.jpg?sqp=-oaymwEbCKgBEF5IVfKriqkDDggBFQAAiEIYAXABwAEG&rs=AOn4CLBCdWvi9OMFi7S3-17Hwrp_DTUzrQ",
+ "width": 168,
+ "height": 94
+ },
+ "medium": {
+ "url": "https://i.ytimg.com/vi/VynI1x3QGI0/hqdefault.jpg?sqp=-oaymwEbCMQBEG5IVfKriqkDDggBFQAAiEIYAXABwAEG&rs=AOn4CLCQVSrMDFGvjkKwAxby7CpIEIzW7A",
+ "width": 196,
+ "height": 110
+ },
+ "high": {
+ "url": "https://i.ytimg.com/vi/VynI1x3QGI0/hqdefault.jpg?sqp=-oaymwEcCPYBEIoBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==&rs=AOn4CLBpMp6cZ5_Y-yRLoi8U02KiG7FdjA",
+ "width": 246,
+ "height": 138
+ },
+ "standard": {
+ "url": "https://i.ytimg.com/vi/VynI1x3QGI0/hqdefault.jpg?sqp=-oaymwEcCNACELwBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==&rs=AOn4CLAH7AHrp7Z9ColRWV4U1GIlynOtlw",
+ "width": 336,
+ "height": 188
+ }
+ }
+ },
+ {
+ "player": "youtube",
+ "id": "Vrgi0hr0Dsk",
+ "title": "20190325 - Consecuencias de la Nueva Directiva de Copyright Europea (y qué puedo hacer)",
+ "pubDate": null,
+ "thumbnails": {
+ "default": {
+ "url": "https://i.ytimg.com/vi/Vrgi0hr0Dsk/hqdefault.jpg?sqp=-oaymwEbCKgBEF5IVfKriqkDDggBFQAAiEIYAXABwAEG&rs=AOn4CLB6IUHz9KXkvVOiZDaxBwj4jadl_Q",
+ "width": 168,
+ "height": 94
+ },
+ "medium": {
+ "url": "https://i.ytimg.com/vi/Vrgi0hr0Dsk/hqdefault.jpg?sqp=-oaymwEbCMQBEG5IVfKriqkDDggBFQAAiEIYAXABwAEG&rs=AOn4CLB29uFL-ltpThWPslOQEfAez7fEpA",
+ "width": 196,
+ "height": 110
+ },
+ "high": {
+ "url": "https://i.ytimg.com/vi/Vrgi0hr0Dsk/hqdefault.jpg?sqp=-oaymwEcCPYBEIoBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==&rs=AOn4CLAI5xRV40HbyQYjoolzs6nyqaMCpQ",
+ "width": 246,
+ "height": 138
+ },
+ "standard": {
+ "url": "https://i.ytimg.com/vi/Vrgi0hr0Dsk/hqdefault.jpg?sqp=-oaymwEcCNACELwBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==&rs=AOn4CLB91tZI_67qLs8wQK7vIUlFhmgNgA",
+ "width": 336,
+ "height": 188
+ }
+ }
+ },
+ {
+ "player": "youtube",
+ "id": "lo6yuYSnAMU",
+ "title": "20190320 - Introducción a las FPGAs+Verilog",
+ "pubDate": null,
+ "thumbnails": {
+ "default": {
+ "url": "https://i.ytimg.com/vi/lo6yuYSnAMU/hqdefault.jpg?sqp=-oaymwEbCKgBEF5IVfKriqkDDggBFQAAiEIYAXABwAEG&rs=AOn4CLDQkMQQ8cC01r1iDVaxsW2L2y7Rug",
+ "width": 168,
+ "height": 94
+ },
+ "medium": {
+ "url": "https://i.ytimg.com/vi/lo6yuYSnAMU/hqdefault.jpg?sqp=-oaymwEbCMQBEG5IVfKriqkDDggBFQAAiEIYAXABwAEG&rs=AOn4CLANrIsi-PSIPtXC-f5yv4h2LVzFXg",
+ "width": 196,
+ "height": 110
+ },
+ "high": {
+ "url": "https://i.ytimg.com/vi/lo6yuYSnAMU/hqdefault.jpg?sqp=-oaymwEcCPYBEIoBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==&rs=AOn4CLAfNHYNWTQOGkkdXpWtPR9MSTaBCQ",
+ "width": 246,
+ "height": 138
+ },
+ "standard": {
+ "url": "https://i.ytimg.com/vi/lo6yuYSnAMU/hqdefault.jpg?sqp=-oaymwEcCNACELwBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==&rs=AOn4CLCSJH9jTIVlx7IrSeD6Y6rvrysnJw",
+ "width": 336,
+ "height": 188
+ }
+ }
+ },
+ {
+ "player": "youtube",
+ "id": "9Ga8hHu1Dig",
+ "title": "20190304 - Charla ganadores Regata Solar 2018 categoría Open",
+ "pubDate": null,
+ "thumbnails": {
+ "default": {
+ "url": "https://i.ytimg.com/vi/9Ga8hHu1Dig/hqdefault.jpg?sqp=-oaymwEbCKgBEF5IVfKriqkDDggBFQAAiEIYAXABwAEG&rs=AOn4CLDD7TRkMa9CMk2vIfhZSBqPRSvdWw",
+ "width": 168,
+ "height": 94
+ },
+ "medium": {
+ "url": "https://i.ytimg.com/vi/9Ga8hHu1Dig/hqdefault.jpg?sqp=-oaymwEbCMQBEG5IVfKriqkDDggBFQAAiEIYAXABwAEG&rs=AOn4CLAW-ulu1lUHk679Pmxe8262b4crHg",
+ "width": 196,
+ "height": 110
+ },
+ "high": {
+ "url": "https://i.ytimg.com/vi/9Ga8hHu1Dig/hqdefault.jpg?sqp=-oaymwEcCPYBEIoBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==&rs=AOn4CLCaWSLj514VsyE9FmRmuUOG3eVlLg",
+ "width": 246,
+ "height": 138
+ },
+ "standard": {
+ "url": "https://i.ytimg.com/vi/9Ga8hHu1Dig/hqdefault.jpg?sqp=-oaymwEcCNACELwBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==&rs=AOn4CLCWGqqYhQoCQpTOfQ3m_gTFV_cG7w",
+ "width": 336,
+ "height": 188
+ }
+ }
+ },
+ {
+ "player": "youtube",
+ "id": "E0sGiBOL7ek",
+ "title": "20190304 - Charla Íñigo Echenique - Diseño Naval - TS Royalist",
+ "pubDate": null,
+ "thumbnails": {
+ "default": {
+ "url": "https://i.ytimg.com/vi/E0sGiBOL7ek/hqdefault.jpg?sqp=-oaymwEbCKgBEF5IVfKriqkDDggBFQAAiEIYAXABwAEG&rs=AOn4CLC5a5haci_ex8xfVKq1OvPXmWsf_w",
+ "width": 168,
+ "height": 94
+ },
+ "medium": {
+ "url": "https://i.ytimg.com/vi/E0sGiBOL7ek/hqdefault.jpg?sqp=-oaymwEbCMQBEG5IVfKriqkDDggBFQAAiEIYAXABwAEG&rs=AOn4CLBfacCWJgM1gR5UiOURLJOtGAQA5g",
+ "width": 196,
+ "height": 110
+ },
+ "high": {
+ "url": "https://i.ytimg.com/vi/E0sGiBOL7ek/hqdefault.jpg?sqp=-oaymwEcCPYBEIoBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==&rs=AOn4CLBk4l3f4jpark_ffwNnT0qw_KmFAA",
+ "width": 246,
+ "height": 138
+ },
+ "standard": {
+ "url": "https://i.ytimg.com/vi/E0sGiBOL7ek/hqdefault.jpg?sqp=-oaymwEcCNACELwBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==&rs=AOn4CLBzjgkLhY-knpe5xe9uafFP7XAmPg",
+ "width": 336,
+ "height": 188
+ }
+ }
+ },
+ {
+ "player": "youtube",
+ "id": "b6ErBdjfBWg",
+ "title": "20190227 - Cómo construirte una impresora 3d XXL",
+ "pubDate": null,
+ "thumbnails": {
+ "default": {
+ "url": "https://i.ytimg.com/vi/b6ErBdjfBWg/hqdefault.jpg?sqp=-oaymwEbCKgBEF5IVfKriqkDDggBFQAAiEIYAXABwAEG&rs=AOn4CLBj0DWvSPOmzEXgEMhzNLLKbQlNdw",
+ "width": 168,
+ "height": 94
+ },
+ "medium": {
+ "url": "https://i.ytimg.com/vi/b6ErBdjfBWg/hqdefault.jpg?sqp=-oaymwEbCMQBEG5IVfKriqkDDggBFQAAiEIYAXABwAEG&rs=AOn4CLBQ4KNe_ZgggH1OyMt6-5WTrVYlZg",
+ "width": 196,
+ "height": 110
+ },
+ "high": {
+ "url": "https://i.ytimg.com/vi/b6ErBdjfBWg/hqdefault.jpg?sqp=-oaymwEcCPYBEIoBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==&rs=AOn4CLAFoHitsWNUdpDECW4xdDlmHvne0A",
+ "width": 246,
+ "height": 138
+ },
+ "standard": {
+ "url": "https://i.ytimg.com/vi/b6ErBdjfBWg/hqdefault.jpg?sqp=-oaymwEcCNACELwBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==&rs=AOn4CLAybyN4extkcliKgLPu9uEEgznWPw",
+ "width": 336,
+ "height": 188
+ }
+ }
+ },
+ {
+ "player": "youtube",
+ "id": "37xmhGWKuAE",
+ "title": "23012019 - Un repaso a las competiciones de robots siguelíneas",
+ "pubDate": null,
+ "thumbnails": {
+ "default": {
+ "url": "https://i.ytimg.com/vi/37xmhGWKuAE/hqdefault.jpg?sqp=-oaymwEbCKgBEF5IVfKriqkDDggBFQAAiEIYAXABwAEG&rs=AOn4CLDUiym6tJJLwItQiSXLbLx9dpnB6w",
+ "width": 168,
+ "height": 94
+ },
+ "medium": {
+ "url": "https://i.ytimg.com/vi/37xmhGWKuAE/hqdefault.jpg?sqp=-oaymwEbCMQBEG5IVfKriqkDDggBFQAAiEIYAXABwAEG&rs=AOn4CLBcHssCzHWkOoqfCzmKIG2j2UxWZg",
+ "width": 196,
+ "height": 110
+ },
+ "high": {
+ "url": "https://i.ytimg.com/vi/37xmhGWKuAE/hqdefault.jpg?sqp=-oaymwEcCPYBEIoBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==&rs=AOn4CLD_gnNkMNiAy2qTC1ICii40zJuXzQ",
+ "width": 246,
+ "height": 138
+ },
+ "standard": {
+ "url": "https://i.ytimg.com/vi/37xmhGWKuAE/hqdefault.jpg?sqp=-oaymwEcCNACELwBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==&rs=AOn4CLBKo89lg2gwrPN4IzxVDxFHMR__RA",
+ "width": 336,
+ "height": 188
+ }
+ }
+ },
+ {
+ "player": "youtube",
+ "id": "UP_HuKoMZco",
+ "title": "20181213 - E-téxtiles nos espacios maker",
+ "pubDate": null,
+ "thumbnails": {
+ "default": {
+ "url": "https://i.ytimg.com/vi/UP_HuKoMZco/hqdefault.jpg?sqp=-oaymwEbCKgBEF5IVfKriqkDDggBFQAAiEIYAXABwAEG&rs=AOn4CLCZZ6gD0lf1Xj2enVawj9MaUQIXVw",
+ "width": 168,
+ "height": 94
+ },
+ "medium": {
+ "url": "https://i.ytimg.com/vi/UP_HuKoMZco/hqdefault.jpg?sqp=-oaymwEbCMQBEG5IVfKriqkDDggBFQAAiEIYAXABwAEG&rs=AOn4CLAmwsUGdwHDHDYrgYvxSHzdiiHVBw",
+ "width": 196,
+ "height": 110
+ },
+ "high": {
+ "url": "https://i.ytimg.com/vi/UP_HuKoMZco/hqdefault.jpg?sqp=-oaymwEcCPYBEIoBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==&rs=AOn4CLDW0DDzDnnXgwwdYGHHDVDB6RMR4w",
+ "width": 246,
+ "height": 138
+ },
+ "standard": {
+ "url": "https://i.ytimg.com/vi/UP_HuKoMZco/hqdefault.jpg?sqp=-oaymwEcCNACELwBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==&rs=AOn4CLDsGOcV47e17Rd5dn0gG07Eez48Ag",
+ "width": 336,
+ "height": 188
+ }
+ }
+ },
+ {
+ "player": "youtube",
+ "id": "OJFnTJlMrOo",
+ "title": "Galicia, el espacio y por qué seguir explorando",
+ "pubDate": null,
+ "thumbnails": {
+ "default": {
+ "url": "https://i.ytimg.com/vi/OJFnTJlMrOo/hqdefault.jpg?sqp=-oaymwEbCKgBEF5IVfKriqkDDggBFQAAiEIYAXABwAEG&rs=AOn4CLCQDtenV0oMUcZiCAjhrbosptjOcA",
+ "width": 168,
+ "height": 94
+ },
+ "medium": {
+ "url": "https://i.ytimg.com/vi/OJFnTJlMrOo/hqdefault.jpg?sqp=-oaymwEbCMQBEG5IVfKriqkDDggBFQAAiEIYAXABwAEG&rs=AOn4CLD-klyjI8BZ0oBE9Vk-4vL6SeTTsA",
+ "width": 196,
+ "height": 110
+ },
+ "high": {
+ "url": "https://i.ytimg.com/vi/OJFnTJlMrOo/hqdefault.jpg?sqp=-oaymwEcCPYBEIoBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==&rs=AOn4CLDv9kRvHAb8SDEmmvTx4jhjww7MMw",
+ "width": 246,
+ "height": 138
+ },
+ "standard": {
+ "url": "https://i.ytimg.com/vi/OJFnTJlMrOo/hqdefault.jpg?sqp=-oaymwEcCNACELwBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==&rs=AOn4CLA8vKHsX1V8S9ts-oZ1NzeREZ49EQ",
+ "width": 336,
+ "height": 188
+ }
+ }
+ },
+ {
+ "player": "youtube",
+ "id": "7oKgu70oDtI",
+ "title": "20180601 - Garabullo - Diego Lale",
+ "pubDate": null,
+ "thumbnails": {
+ "default": {
+ "url": "https://i.ytimg.com/vi/7oKgu70oDtI/hqdefault.jpg?sqp=-oaymwEbCKgBEF5IVfKriqkDDggBFQAAiEIYAXABwAEG&rs=AOn4CLCRoOTK3I2mjHPaoxhiUSJuyVCLXA",
+ "width": 168,
+ "height": 94
+ },
+ "medium": {
+ "url": "https://i.ytimg.com/vi/7oKgu70oDtI/hqdefault.jpg?sqp=-oaymwEbCMQBEG5IVfKriqkDDggBFQAAiEIYAXABwAEG&rs=AOn4CLBrnXgKnDI8pmn3SqftAXQTA0reFQ",
+ "width": 196,
+ "height": 110
+ },
+ "high": {
+ "url": "https://i.ytimg.com/vi/7oKgu70oDtI/hqdefault.jpg?sqp=-oaymwEcCPYBEIoBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==&rs=AOn4CLAqika3RHIuAMtBKPbOnAMkeZPG1g",
+ "width": 246,
+ "height": 138
+ },
+ "standard": {
+ "url": "https://i.ytimg.com/vi/7oKgu70oDtI/hqdefault.jpg?sqp=-oaymwEcCNACELwBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==&rs=AOn4CLBbBtvCzM9Qx8TnJtZ5aGBvJQDktA",
+ "width": 336,
+ "height": 188
+ }
+ }
+ },
+ {
+ "player": "youtube",
+ "id": "Kx2P4b1cxCk",
+ "title": "20180301 - Monitorización de una regata de barcos radiocontrol",
+ "pubDate": null,
+ "thumbnails": {
+ "default": {
+ "url": "https://i.ytimg.com/vi/Kx2P4b1cxCk/hqdefault.jpg?sqp=-oaymwEbCKgBEF5IVfKriqkDDggBFQAAiEIYAXABwAEG&rs=AOn4CLDeoBdKiJaZJ6m7ZzHGD1fdlGw6qw",
+ "width": 168,
+ "height": 94
+ },
+ "medium": {
+ "url": "https://i.ytimg.com/vi/Kx2P4b1cxCk/hqdefault.jpg?sqp=-oaymwEbCMQBEG5IVfKriqkDDggBFQAAiEIYAXABwAEG&rs=AOn4CLCVk3J8FC95MSYEnPadfkgWzf42sA",
+ "width": 196,
+ "height": 110
+ },
+ "high": {
+ "url": "https://i.ytimg.com/vi/Kx2P4b1cxCk/hqdefault.jpg?sqp=-oaymwEcCPYBEIoBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==&rs=AOn4CLAFqS0MT6y8AirMP8kLitipAsylig",
+ "width": 246,
+ "height": 138
+ },
+ "standard": {
+ "url": "https://i.ytimg.com/vi/Kx2P4b1cxCk/hqdefault.jpg?sqp=-oaymwEcCNACELwBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==&rs=AOn4CLAQtgx6tz6CsJVjnF6C-PxC9jlsBg",
+ "width": 336,
+ "height": 188
+ }
+ }
+ },
+ {
+ "player": "youtube",
+ "id": "Eply147XQZw",
+ "title": "20180309 - Robótica de competición (Carreras, mini-sumo y humanoides) - OPROBOTS",
+ "pubDate": null,
+ "thumbnails": {
+ "default": {
+ "url": "https://i.ytimg.com/vi/Eply147XQZw/hqdefault.jpg?sqp=-oaymwEbCKgBEF5IVfKriqkDDggBFQAAiEIYAXABwAEG&rs=AOn4CLCwn9CNBOgw5hfDI3kx_k0KoWUyHQ",
+ "width": 168,
+ "height": 94
+ },
+ "medium": {
+ "url": "https://i.ytimg.com/vi/Eply147XQZw/hqdefault.jpg?sqp=-oaymwEbCMQBEG5IVfKriqkDDggBFQAAiEIYAXABwAEG&rs=AOn4CLA0Q3s10-G4e92g0-qjDSO8rY4jZA",
+ "width": 196,
+ "height": 110
+ },
+ "high": {
+ "url": "https://i.ytimg.com/vi/Eply147XQZw/hqdefault.jpg?sqp=-oaymwEcCPYBEIoBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==&rs=AOn4CLAgY0oEaQGNfAXlFg0A8atD0yQSCA",
+ "width": 246,
+ "height": 138
+ },
+ "standard": {
+ "url": "https://i.ytimg.com/vi/Eply147XQZw/hqdefault.jpg?sqp=-oaymwEcCNACELwBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==&rs=AOn4CLDCa_jcmm2jmBnG61pts0Avy1lECQ",
+ "width": 336,
+ "height": 188
+ }
+ }
+ },
+ {
+ "player": "youtube",
+ "id": "ReZbM9lhdH4",
+ "title": "20180314 - Introducción al diseño naval - III Regata Solar - Íñigo Echenique",
+ "pubDate": null,
+ "thumbnails": {
+ "default": {
+ "url": "https://i.ytimg.com/vi/ReZbM9lhdH4/hqdefault.jpg?sqp=-oaymwEbCKgBEF5IVfKriqkDDggBFQAAiEIYAXABwAEG&rs=AOn4CLDTqHY4ZtYVL9Tf-5PhXUsLHESDsQ",
+ "width": 168,
+ "height": 94
+ },
+ "medium": {
+ "url": "https://i.ytimg.com/vi/ReZbM9lhdH4/hqdefault.jpg?sqp=-oaymwEbCMQBEG5IVfKriqkDDggBFQAAiEIYAXABwAEG&rs=AOn4CLBgJlmPnVCGHeC_2qtHWMR3wxYJ1w",
+ "width": 196,
+ "height": 110
+ },
+ "high": {
+ "url": "https://i.ytimg.com/vi/ReZbM9lhdH4/hqdefault.jpg?sqp=-oaymwEcCPYBEIoBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==&rs=AOn4CLBqHYmgbOjB5sbIiiBC74Ig2Wsiag",
+ "width": 246,
+ "height": 138
+ },
+ "standard": {
+ "url": "https://i.ytimg.com/vi/ReZbM9lhdH4/hqdefault.jpg?sqp=-oaymwEcCNACELwBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==&rs=AOn4CLAreF2SzojhDu32tSX4n_5jruApmg",
+ "width": 336,
+ "height": 188
+ }
+ }
+ },
+ {
+ "player": "youtube",
+ "id": "R1CZGU-SWsA",
+ "title": "20180216 - Bulebule - Making of de un robot \"micromouse\"",
+ "pubDate": null,
+ "thumbnails": {
+ "default": {
+ "url": "https://i.ytimg.com/vi/R1CZGU-SWsA/hqdefault.jpg?sqp=-oaymwE1CKgBEF5IVfKriqkDKAgBFQAAiEIYAXABwAEG8AEB-AH-CYAC0AWKAgwIABABGGYgZihmMA8=&rs=AOn4CLA05qDhqGLoiksaTu84jTzR8JlsLQ",
+ "width": 168,
+ "height": 94
+ },
+ "medium": {
+ "url": "https://i.ytimg.com/vi/R1CZGU-SWsA/hqdefault.jpg?sqp=-oaymwE1CMQBEG5IVfKriqkDKAgBFQAAiEIYAXABwAEG8AEB-AH-CYAC0AWKAgwIABABGGYgZihmMA8=&rs=AOn4CLANjlnIjEnMu8qoDCBmMNVCA_H2tw",
+ "width": 196,
+ "height": 110
+ },
+ "high": {
+ "url": "https://i.ytimg.com/vi/R1CZGU-SWsA/hqdefault.jpg?sqp=-oaymwE2CPYBEIoBSFXyq4qpAygIARUAAIhCGAFwAcABBvABAfgB_gmAAtAFigIMCAAQARhmIGYoZjAP&rs=AOn4CLA6L4yCWIp7aPJrkWFjVEPBriKdSg",
+ "width": 246,
+ "height": 138
+ },
+ "standard": {
+ "url": "https://i.ytimg.com/vi/R1CZGU-SWsA/hqdefault.jpg?sqp=-oaymwE2CNACELwBSFXyq4qpAygIARUAAIhCGAFwAcABBvABAfgB_gmAAtAFigIMCAAQARhmIGYoZjAP&rs=AOn4CLAeH7osLarFdp6JB7EgHTQxwloL9g",
+ "width": 336,
+ "height": 188
+ }
+ }
+ },
+ {
+ "player": "youtube",
+ "id": "ygDE-hWi2-M",
+ "title": "20180123 - TVG - Entrevista a Ana Cidre",
+ "pubDate": null,
+ "thumbnails": {
+ "default": {
+ "url": "https://i.ytimg.com/vi/ygDE-hWi2-M/hqdefault.jpg?sqp=-oaymwEbCKgBEF5IVfKriqkDDggBFQAAiEIYAXABwAEG&rs=AOn4CLCxOL4JdUFVcwEVLCAYWpTLi9cJDA",
+ "width": 168,
+ "height": 94
+ },
+ "medium": {
+ "url": "https://i.ytimg.com/vi/ygDE-hWi2-M/hqdefault.jpg?sqp=-oaymwEbCMQBEG5IVfKriqkDDggBFQAAiEIYAXABwAEG&rs=AOn4CLBx7FNHk3pcfMAtT5iyTiH0l-VPRw",
+ "width": 196,
+ "height": 110
+ },
+ "high": {
+ "url": "https://i.ytimg.com/vi/ygDE-hWi2-M/hqdefault.jpg?sqp=-oaymwEcCPYBEIoBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==&rs=AOn4CLCYSvhwGBCy6WGpll48aHH92I81kA",
+ "width": 246,
+ "height": 138
+ },
+ "standard": {
+ "url": "https://i.ytimg.com/vi/ygDE-hWi2-M/hqdefault.jpg?sqp=-oaymwEcCNACELwBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==&rs=AOn4CLD9draHZNYFlEJ2WeS7Cdt-d9TrqQ",
+ "width": 336,
+ "height": 188
+ }
+ }
+ },
+ {
+ "player": "youtube",
+ "id": "M9BeEq0OSq8",
+ "title": "VigoTech na TVG",
+ "pubDate": null,
+ "thumbnails": {
+ "default": {
+ "url": "https://i.ytimg.com/vi/M9BeEq0OSq8/hqdefault.jpg?sqp=-oaymwEbCKgBEF5IVfKriqkDDggBFQAAiEIYAXABwAEG&rs=AOn4CLD5HOMvnlKpmsoKdZMwaC6JMPUocQ",
+ "width": 168,
+ "height": 94
+ },
+ "medium": {
+ "url": "https://i.ytimg.com/vi/M9BeEq0OSq8/hqdefault.jpg?sqp=-oaymwEbCMQBEG5IVfKriqkDDggBFQAAiEIYAXABwAEG&rs=AOn4CLDthxqneymxRArAWTiJncki6QZbsg",
+ "width": 196,
+ "height": 110
+ },
+ "high": {
+ "url": "https://i.ytimg.com/vi/M9BeEq0OSq8/hqdefault.jpg?sqp=-oaymwEcCPYBEIoBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==&rs=AOn4CLDywFYlrXCgL8ZgeUFYuOfWq3RMzA",
+ "width": 246,
+ "height": 138
+ },
+ "standard": {
+ "url": "https://i.ytimg.com/vi/M9BeEq0OSq8/hqdefault.jpg?sqp=-oaymwEcCNACELwBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==&rs=AOn4CLAsgj-FgwowiXpt-YqKbpyktVNTcg",
+ "width": 336,
+ "height": 188
+ }
+ }
+ },
+ {
+ "player": "youtube",
+ "id": "w3BInWruN88",
+ "title": "Time-lapse da montaxe Scanner 3D Ciclop",
+ "pubDate": null,
+ "thumbnails": {
+ "default": {
+ "url": "https://i.ytimg.com/vi/w3BInWruN88/hqdefault.jpg?sqp=-oaymwEbCKgBEF5IVfKriqkDDggBFQAAiEIYAXABwAEG&rs=AOn4CLBrsMrEQcZnDz165Q5avNbjOb_wZA",
+ "width": 168,
+ "height": 94
+ },
+ "medium": {
+ "url": "https://i.ytimg.com/vi/w3BInWruN88/hqdefault.jpg?sqp=-oaymwEbCMQBEG5IVfKriqkDDggBFQAAiEIYAXABwAEG&rs=AOn4CLAgAY_fCGR6PV3o_4hRU9hUjnCZ7A",
+ "width": 196,
+ "height": 110
+ },
+ "high": {
+ "url": "https://i.ytimg.com/vi/w3BInWruN88/hqdefault.jpg?sqp=-oaymwEcCPYBEIoBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==&rs=AOn4CLCNVY_CGMHPOd0I3pQxmlWfUja08w",
+ "width": 246,
+ "height": 138
+ },
+ "standard": {
+ "url": "https://i.ytimg.com/vi/w3BInWruN88/hqdefault.jpg?sqp=-oaymwEcCNACELwBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==&rs=AOn4CLAB0N6hiOIdOMk4JfQlRsZWy8SC-A",
+ "width": 336,
+ "height": 188
+ }
+ }
+ },
+ {
+ "player": "youtube",
+ "id": "bR0vVThAn6o",
+ "title": "A Industriosa no telexornal da TVG",
+ "pubDate": null,
+ "thumbnails": {
+ "default": {
+ "url": "https://i.ytimg.com/vi/bR0vVThAn6o/hqdefault.jpg?sqp=-oaymwEbCKgBEF5IVfKriqkDDggBFQAAiEIYAXABwAEG&rs=AOn4CLAfL9s4uVAIOQ-pVRRQ5AE4xT5UKQ",
+ "width": 168,
+ "height": 94
+ },
+ "medium": {
+ "url": "https://i.ytimg.com/vi/bR0vVThAn6o/hqdefault.jpg?sqp=-oaymwEbCMQBEG5IVfKriqkDDggBFQAAiEIYAXABwAEG&rs=AOn4CLAxXxU7NvgCxR8DuS8aUKidEKUiQQ",
+ "width": 196,
+ "height": 110
+ },
+ "high": {
+ "url": "https://i.ytimg.com/vi/bR0vVThAn6o/hqdefault.jpg?sqp=-oaymwEcCPYBEIoBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==&rs=AOn4CLA1Nr-dR9FabKXCIN4y4CXLRY8dkw",
+ "width": 246,
+ "height": 138
+ },
+ "standard": {
+ "url": "https://i.ytimg.com/vi/bR0vVThAn6o/hqdefault.jpg?sqp=-oaymwEcCNACELwBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==&rs=AOn4CLDmVkXC4cBphwFVcTwhGGy1jEBRXA",
+ "width": 336,
+ "height": 188
+ }
+ }
+ },
+ {
+ "player": "youtube",
+ "id": "cRS2oFs_aqw",
+ "title": "A Industriosa en Localia",
+ "pubDate": null,
+ "thumbnails": {
+ "default": {
+ "url": "https://i.ytimg.com/vi/cRS2oFs_aqw/hqdefault.jpg?sqp=-oaymwEbCKgBEF5IVfKriqkDDggBFQAAiEIYAXABwAEG&rs=AOn4CLDq-W09BYYC17dVQNJ44pDgzOd8EA",
+ "width": 168,
+ "height": 94
+ },
+ "medium": {
+ "url": "https://i.ytimg.com/vi/cRS2oFs_aqw/hqdefault.jpg?sqp=-oaymwEbCMQBEG5IVfKriqkDDggBFQAAiEIYAXABwAEG&rs=AOn4CLCykvir300IGPymnaotct-b3Sk4dA",
+ "width": 196,
+ "height": 110
+ },
+ "high": {
+ "url": "https://i.ytimg.com/vi/cRS2oFs_aqw/hqdefault.jpg?sqp=-oaymwEcCPYBEIoBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==&rs=AOn4CLCeU6XcHKkw7DMw2IyvOxM3AXtajw",
+ "width": 246,
+ "height": 138
+ },
+ "standard": {
+ "url": "https://i.ytimg.com/vi/cRS2oFs_aqw/hqdefault.jpg?sqp=-oaymwEcCNACELwBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==&rs=AOn4CLBkYHA8xH3O1-EAuSWkEo-kS97AQg",
+ "width": 336,
+ "height": 188
+ }
+ }
+ },
+ {
+ "player": "youtube",
+ "id": "7mVK7obSv80",
+ "title": "A Industriosa - Promo",
+ "pubDate": null,
+ "thumbnails": {
+ "default": {
+ "url": "https://i.ytimg.com/vi/7mVK7obSv80/hqdefault.jpg?sqp=-oaymwEbCKgBEF5IVfKriqkDDggBFQAAiEIYAXABwAEG&rs=AOn4CLCJXbvtbWuplpjW9N35Uhdxbwmh7Q",
+ "width": 168,
+ "height": 94
+ },
+ "medium": {
+ "url": "https://i.ytimg.com/vi/7mVK7obSv80/hqdefault.jpg?sqp=-oaymwEbCMQBEG5IVfKriqkDDggBFQAAiEIYAXABwAEG&rs=AOn4CLAsqeZwlNTgtxy_07SLxbaSIxu_ww",
+ "width": 196,
+ "height": 110
+ },
+ "high": {
+ "url": "https://i.ytimg.com/vi/7mVK7obSv80/hqdefault.jpg?sqp=-oaymwEcCPYBEIoBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==&rs=AOn4CLCA4bCsVeG5frSwFyv2xI2FjuKiNA",
+ "width": 246,
+ "height": 138
+ },
+ "standard": {
+ "url": "https://i.ytimg.com/vi/7mVK7obSv80/hqdefault.jpg?sqp=-oaymwEcCNACELwBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==&rs=AOn4CLCtK_cXRX8dm3oAGd6bfbhMNe35Aw",
+ "width": 336,
+ "height": 188
+ }
+ }
+ },
+ {
+ "player": "youtube",
+ "id": "nf8a_OrQSSI",
+ "title": "Badge OSHWDem 2017",
+ "pubDate": null,
+ "thumbnails": {
+ "default": {
+ "url": "https://i.ytimg.com/vi/nf8a_OrQSSI/hqdefault.jpg?sqp=-oaymwEbCKgBEF5IVfKriqkDDggBFQAAiEIYAXABwAEG&rs=AOn4CLDXhTC5pL0D3ELvth92jDzHg8hXCQ",
+ "width": 168,
+ "height": 94
+ },
+ "medium": {
+ "url": "https://i.ytimg.com/vi/nf8a_OrQSSI/hqdefault.jpg?sqp=-oaymwEbCMQBEG5IVfKriqkDDggBFQAAiEIYAXABwAEG&rs=AOn4CLCJxvwzGTi3CZrCZu10R_nVxWTIcQ",
+ "width": 196,
+ "height": 110
+ },
+ "high": {
+ "url": "https://i.ytimg.com/vi/nf8a_OrQSSI/hqdefault.jpg?sqp=-oaymwEcCPYBEIoBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==&rs=AOn4CLD5Buz3JHHJxRM5mhFyKAij0ewmXg",
+ "width": 246,
+ "height": 138
+ },
+ "standard": {
+ "url": "https://i.ytimg.com/vi/nf8a_OrQSSI/hqdefault.jpg?sqp=-oaymwEcCNACELwBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==&rs=AOn4CLBXxCQYyYkvBXdE3MKL0U1HjYn12g",
+ "width": 336,
+ "height": 188
+ }
+ }
+ }
+ ],
+ "eventList": []
+ },
+ "blockchaingal": {
+ "name": "Blockchain.gal Vigo",
+ "logo": "https://vigotech.org/images/blockchaingal.png",
+ "links": {
+ "web": "https://blockchain.gal/",
+ "twitter": "https://twitter.com/blockchain_gal",
+ "meetup": "https://www.meetup.com/es-ES/blockchain_gal_vigo/",
+ "github": "https://github.com/blockchain-gal"
+ },
+ "events": {
+ "type": "meetup",
+ "meetupid": "blockchain_gal_vigo"
+ },
+ "inactive": true,
+ "nextEvent": null,
+ "videoList": [],
+ "eventList": []
+ },
+ "craftersvigo": {
+ "name": "Crafters Vigo",
+ "logo": "https://vigotech.org/images/craftersVigo.png",
+ "links": {
+ "twitter": "https://twitter.com/CraftersVigo",
+ "meetup": "https://www.meetup.com/craftersvigo/"
+ },
+ "events": {
+ "type": "meetup",
+ "meetupid": "craftersvigo"
+ },
+ "nextEvent": null,
+ "videoList": [],
+ "eventList": []
+ },
+ "galpon": {
+ "name": "GALPon",
+ "logo": "https://vigotech.org/images/galpon.png",
+ "links": {
+ "web": "https://www.galpon.org",
+ "twitter": "https://twitter.com/galpon",
+ "maillist": "https://www.galpon.org/content/listas-correo-galpon"
+ },
+ "nextEvent": null,
+ "videoList": [],
+ "eventList": []
+ },
+ "galstech": {
+ "name": "GalsTech",
+ "logo": "https://vigotech.org/images/galstech.png",
+ "links": {
+ "meetup": "https://www.meetup.com/GalsTech/",
+ "twitter": "https://twitter.com/galstech_?lang=es"
+ },
+ "events": {
+ "type": "meetup",
+ "meetupid": "galstech"
+ },
+ "inactive": true,
+ "nextEvent": null,
+ "videoList": [],
+ "eventList": []
+ },
+ "gdgvigo": {
+ "name": "GDG Vigo",
+ "logo": "https://vigotech.org/images/gdg_vigo.png",
+ "links": {
+ "twitter": "http://twitter.com/GDGVigo/",
+ "meetup": "https://www.meetup.com/es-ES/GDGVigo/?chapter_analytics_code=UA-73757047-1",
+ "youtube": "https://www.youtube.com/user/GDGVigo"
+ },
+ "events": [
+ {
+ "type": "meetup",
+ "meetupid": "GDGVigo"
+ }
+ ],
+ "videos": [
+ {
+ "type": "youtube",
+ "channel_id": "UC3BXzHGAMx7tAgVD1CqCuCQ"
+ }
+ ],
+ "inactive": true,
+ "nextEvent": null,
+ "videoList": [
+ {
+ "player": "youtube",
+ "id": "85V3Pl50Yl4",
+ "title": "GDG Vigo - Web Components y Polymer",
+ "pubDate": 1441652288000,
+ "thumbnails": {
+ "default": {
+ "url": "https://i.ytimg.com/vi/85V3Pl50Yl4/default.jpg",
+ "width": 120,
+ "height": 90
+ },
+ "medium": {
+ "url": "https://i.ytimg.com/vi/85V3Pl50Yl4/mqdefault.jpg",
+ "width": 320,
+ "height": 180
+ },
+ "high": {
+ "url": "https://i.ytimg.com/vi/85V3Pl50Yl4/hqdefault.jpg",
+ "width": 480,
+ "height": 360
+ }
+ }
+ },
+ {
+ "player": "youtube",
+ "id": "u4KYKUbpg6c",
+ "title": "GDG Vigo - Python y Django",
+ "pubDate": 1441650886000,
+ "thumbnails": {
+ "default": {
+ "url": "https://i.ytimg.com/vi/u4KYKUbpg6c/default.jpg",
+ "width": 120,
+ "height": 90
+ },
+ "medium": {
+ "url": "https://i.ytimg.com/vi/u4KYKUbpg6c/mqdefault.jpg",
+ "width": 320,
+ "height": 180
+ },
+ "high": {
+ "url": "https://i.ytimg.com/vi/u4KYKUbpg6c/hqdefault.jpg",
+ "width": 480,
+ "height": 360
+ }
+ }
+ },
+ {
+ "player": "youtube",
+ "id": "RLceJ7Ob2yQ",
+ "title": "Floppy disks By Breogan and Alberto",
+ "pubDate": 1401118959000,
+ "thumbnails": {
+ "default": {
+ "url": "https://i.ytimg.com/vi/RLceJ7Ob2yQ/default.jpg",
+ "width": 120,
+ "height": 90
+ },
+ "medium": {
+ "url": "https://i.ytimg.com/vi/RLceJ7Ob2yQ/mqdefault.jpg",
+ "width": 320,
+ "height": 180
+ },
+ "high": {
+ "url": "https://i.ytimg.com/vi/RLceJ7Ob2yQ/hqdefault.jpg",
+ "width": 480,
+ "height": 360
+ }
+ }
+ }
+ ],
+ "eventList": []
+ },
+ "joomlavigo": {
+ "name": "Grupo de Usuarios de Joomla de Vigo",
+ "logo": "https://vigotech.org/images/joomla_vigo.png",
+ "links": {
+ "web": "https://www.joomlavigo.es/",
+ "twitter": "https://twitter.com/JoomlaVigo",
+ "facebook": "https://www.facebook.com/JoomlaVigo/"
+ },
+ "nextEvent": null,
+ "videoList": [],
+ "eventList": []
+ },
+ "phpvigo": {
+ "name": "PHPVigo",
+ "logo": "https://vigotech.org/images/php_vigo.jpg",
+ "links": {
+ "web": "http://phpvigo.com/",
+ "meetup": "https://www.meetup.com/es-ES/PHPVigo/",
+ "twitter": "https://twitter.com/phpvigo",
+ "github": "https://github.com/phpvigo",
+ "youtube": "https://www.youtube.com/c/phpvigo"
+ },
+ "events": [
+ {
+ "type": "meetup",
+ "meetupid": "phpvigo"
+ },
+ {
+ "type": "json",
+ "source": "https://www.phpvigo.com/events.json"
+ }
+ ],
+ "videos": [
+ {
+ "type": "youtube",
+ "channel_id": "UCzcSOwRc7bfKs9jPehJRNxQ"
+ }
+ ],
+ "inactive": true,
+ "nextEvent": null,
+ "videoList": [
+ {
+ "player": "youtube",
+ "id": "3WSDxMK9MIw",
+ "title": "PHPVigo #40: New no, lo siguiente. Patrones de creación de objetos 🔊 Fran Iglesias",
+ "pubDate": 1604480727000,
+ "thumbnails": {
+ "default": {
+ "url": "https://i.ytimg.com/vi/3WSDxMK9MIw/default.jpg",
+ "width": 120,
+ "height": 90
+ },
+ "medium": {
+ "url": "https://i.ytimg.com/vi/3WSDxMK9MIw/mqdefault.jpg",
+ "width": 320,
+ "height": 180
+ },
+ "high": {
+ "url": "https://i.ytimg.com/vi/3WSDxMK9MIw/hqdefault.jpg",
+ "width": 480,
+ "height": 360
+ }
+ }
+ },
+ {
+ "player": "youtube",
+ "id": "z_K5iuSjCDo",
+ "title": "PHPVigo 39: \"Crea tu propia librería de componentes Vue. From scratch to NPM\"",
+ "pubDate": 1601453780000,
+ "thumbnails": {
+ "default": {
+ "url": "https://i.ytimg.com/vi/z_K5iuSjCDo/default.jpg",
+ "width": 120,
+ "height": 90
+ },
+ "medium": {
+ "url": "https://i.ytimg.com/vi/z_K5iuSjCDo/mqdefault.jpg",
+ "width": 320,
+ "height": 180
+ },
+ "high": {
+ "url": "https://i.ytimg.com/vi/z_K5iuSjCDo/hqdefault.jpg",
+ "width": 480,
+ "height": 360
+ }
+ }
+ },
+ {
+ "player": "youtube",
+ "id": "iyj-exTcbyQ",
+ "title": "PHPVigo #38: \"Monta una API con ReactPHP\" (Dev Streaming)",
+ "pubDate": 1596136540000,
+ "thumbnails": {
+ "default": {
+ "url": "https://i.ytimg.com/vi/iyj-exTcbyQ/default.jpg",
+ "width": 120,
+ "height": 90
+ },
+ "medium": {
+ "url": "https://i.ytimg.com/vi/iyj-exTcbyQ/mqdefault.jpg",
+ "width": 320,
+ "height": 180
+ },
+ "high": {
+ "url": "https://i.ytimg.com/vi/iyj-exTcbyQ/hqdefault.jpg",
+ "width": 480,
+ "height": 360
+ }
+ }
+ },
+ {
+ "player": "youtube",
+ "id": "ziZO5KQM_KU",
+ "title": "PHPVigo #37 - La nueva normalidad dev stream",
+ "pubDate": 1595059609000,
+ "thumbnails": {
+ "default": {
+ "url": "https://i.ytimg.com/vi/ziZO5KQM_KU/default.jpg",
+ "width": 120,
+ "height": 90
+ },
+ "medium": {
+ "url": "https://i.ytimg.com/vi/ziZO5KQM_KU/mqdefault.jpg",
+ "width": 320,
+ "height": 180
+ },
+ "high": {
+ "url": "https://i.ytimg.com/vi/ziZO5KQM_KU/hqdefault.jpg",
+ "width": 480,
+ "height": 360
+ }
+ }
+ },
+ {
+ "player": "youtube",
+ "id": "oUZ-mqFcCuY",
+ "title": "Testing && Pizza - Álvaro Gómez (@lito_ordes)",
+ "pubDate": 1517559810000,
+ "thumbnails": {
+ "default": {
+ "url": "https://i.ytimg.com/vi/oUZ-mqFcCuY/default.jpg",
+ "width": 120,
+ "height": 90
+ },
+ "medium": {
+ "url": "https://i.ytimg.com/vi/oUZ-mqFcCuY/mqdefault.jpg",
+ "width": 320,
+ "height": 180
+ },
+ "high": {
+ "url": "https://i.ytimg.com/vi/oUZ-mqFcCuY/hqdefault.jpg",
+ "width": 480,
+ "height": 360
+ }
+ }
+ },
+ {
+ "player": "youtube",
+ "id": "3n3aK0DYJq4",
+ "title": "Novedades PHP 7.2 con Raúl Araya",
+ "pubDate": 1517558746000,
+ "thumbnails": {
+ "default": {
+ "url": "https://i.ytimg.com/vi/3n3aK0DYJq4/default.jpg",
+ "width": 120,
+ "height": 90
+ },
+ "medium": {
+ "url": "https://i.ytimg.com/vi/3n3aK0DYJq4/mqdefault.jpg",
+ "width": 320,
+ "height": 180
+ },
+ "high": {
+ "url": "https://i.ytimg.com/vi/3n3aK0DYJq4/hqdefault.jpg",
+ "width": 480,
+ "height": 360
+ }
+ }
+ },
+ {
+ "player": "youtube",
+ "id": "KwydgooyO2o",
+ "title": "Symfony 4 con David Negreira",
+ "pubDate": 1517558631000,
+ "thumbnails": {
+ "default": {
+ "url": "https://i.ytimg.com/vi/KwydgooyO2o/default.jpg",
+ "width": 120,
+ "height": 90
+ },
+ "medium": {
+ "url": "https://i.ytimg.com/vi/KwydgooyO2o/mqdefault.jpg",
+ "width": 320,
+ "height": 180
+ },
+ "high": {
+ "url": "https://i.ytimg.com/vi/KwydgooyO2o/hqdefault.jpg",
+ "width": 480,
+ "height": 360
+ }
+ }
+ },
+ {
+ "player": "youtube",
+ "id": "uC1f88SGFJI",
+ "title": "Facturascripts 2018 técnico",
+ "pubDate": 1512029706000,
+ "thumbnails": {
+ "default": {
+ "url": "https://i.ytimg.com/vi/uC1f88SGFJI/default.jpg",
+ "width": 120,
+ "height": 90
+ },
+ "medium": {
+ "url": "https://i.ytimg.com/vi/uC1f88SGFJI/mqdefault.jpg",
+ "width": 320,
+ "height": 180
+ },
+ "high": {
+ "url": "https://i.ytimg.com/vi/uC1f88SGFJI/hqdefault.jpg",
+ "width": 480,
+ "height": 360
+ }
+ }
+ },
+ {
+ "player": "youtube",
+ "id": "ufGsMAzA42c",
+ "title": "Rolando Caldas - Password Hash",
+ "pubDate": 1512029162000,
+ "thumbnails": {
+ "default": {
+ "url": "https://i.ytimg.com/vi/ufGsMAzA42c/default.jpg",
+ "width": 120,
+ "height": 90
+ },
+ "medium": {
+ "url": "https://i.ytimg.com/vi/ufGsMAzA42c/mqdefault.jpg",
+ "width": 320,
+ "height": 180
+ },
+ "high": {
+ "url": "https://i.ytimg.com/vi/ufGsMAzA42c/hqdefault.jpg",
+ "width": 480,
+ "height": 360
+ }
+ }
+ },
+ {
+ "player": "youtube",
+ "id": "NftbtvsTShE",
+ "title": "Meetup #15: ¡No sin Composer! Carlos Goce (@carlosgoce)",
+ "pubDate": 1507036022000,
+ "thumbnails": {
+ "default": {
+ "url": "https://i.ytimg.com/vi/NftbtvsTShE/default.jpg",
+ "width": 120,
+ "height": 90
+ },
+ "medium": {
+ "url": "https://i.ytimg.com/vi/NftbtvsTShE/mqdefault.jpg",
+ "width": 320,
+ "height": 180
+ },
+ "high": {
+ "url": "https://i.ytimg.com/vi/NftbtvsTShE/hqdefault.jpg",
+ "width": 480,
+ "height": 360
+ }
+ }
+ },
+ {
+ "player": "youtube",
+ "id": "txWbsVM2Rx0",
+ "title": "PHP Slim Api Rest (Fernando Freire)",
+ "pubDate": 1507035616000,
+ "thumbnails": {
+ "default": {
+ "url": "https://i.ytimg.com/vi/txWbsVM2Rx0/default.jpg",
+ "width": 120,
+ "height": 90
+ },
+ "medium": {
+ "url": "https://i.ytimg.com/vi/txWbsVM2Rx0/mqdefault.jpg",
+ "width": 320,
+ "height": 180
+ },
+ "high": {
+ "url": "https://i.ytimg.com/vi/txWbsVM2Rx0/hqdefault.jpg",
+ "width": 480,
+ "height": 360
+ }
+ }
+ },
+ {
+ "player": "youtube",
+ "id": "8mRFrByfFpM",
+ "title": "Double Extension Attack (@sergiocarracedo)",
+ "pubDate": 1507017150000,
+ "thumbnails": {
+ "default": {
+ "url": "https://i.ytimg.com/vi/8mRFrByfFpM/default.jpg",
+ "width": 120,
+ "height": 90
+ },
+ "medium": {
+ "url": "https://i.ytimg.com/vi/8mRFrByfFpM/mqdefault.jpg",
+ "width": 320,
+ "height": 180
+ },
+ "high": {
+ "url": "https://i.ytimg.com/vi/8mRFrByfFpM/hqdefault.jpg",
+ "width": 480,
+ "height": 360
+ }
+ }
+ },
+ {
+ "player": "youtube",
+ "id": "p4vdyLUsqHw",
+ "title": "Encabezados HTTP de seguridade @rocasan_",
+ "pubDate": 1507017150000,
+ "thumbnails": {
+ "default": {
+ "url": "https://i.ytimg.com/vi/p4vdyLUsqHw/default.jpg",
+ "width": 120,
+ "height": 90
+ },
+ "medium": {
+ "url": "https://i.ytimg.com/vi/p4vdyLUsqHw/mqdefault.jpg",
+ "width": 320,
+ "height": 180
+ },
+ "high": {
+ "url": "https://i.ytimg.com/vi/p4vdyLUsqHw/hqdefault.jpg",
+ "width": 480,
+ "height": 360
+ }
+ }
+ },
+ {
+ "player": "youtube",
+ "id": "umssjHE5yG0",
+ "title": "Filter Input (@rolando_caldas)",
+ "pubDate": 1507017150000,
+ "thumbnails": {
+ "default": {
+ "url": "https://i.ytimg.com/vi/umssjHE5yG0/default.jpg",
+ "width": 120,
+ "height": 90
+ },
+ "medium": {
+ "url": "https://i.ytimg.com/vi/umssjHE5yG0/mqdefault.jpg",
+ "width": 320,
+ "height": 180
+ },
+ "high": {
+ "url": "https://i.ytimg.com/vi/umssjHE5yG0/hqdefault.jpg",
+ "width": 480,
+ "height": 360
+ }
+ }
+ },
+ {
+ "player": "youtube",
+ "id": "NbeP64e8DZQ",
+ "title": "CSS Grid Layout: El futuro ya está aquí",
+ "pubDate": 1493754893000,
+ "thumbnails": {
+ "default": {
+ "url": "https://i.ytimg.com/vi/NbeP64e8DZQ/default.jpg",
+ "width": 120,
+ "height": 90
+ },
+ "medium": {
+ "url": "https://i.ytimg.com/vi/NbeP64e8DZQ/mqdefault.jpg",
+ "width": 320,
+ "height": 180
+ },
+ "high": {
+ "url": "https://i.ytimg.com/vi/NbeP64e8DZQ/hqdefault.jpg",
+ "width": 480,
+ "height": 360
+ }
+ }
+ },
+ {
+ "player": "youtube",
+ "id": "4HsGaWqB20g",
+ "title": "2017 04 26 21 44 12",
+ "pubDate": null,
+ "thumbnails": {
+ "default": {
+ "url": "https://i.ytimg.com/vi/4HsGaWqB20g/hqdefault.jpg?sqp=-oaymwEbCKgBEF5IVfKriqkDDggBFQAAiEIYAXABwAEG&rs=AOn4CLBouP2QWiJs0tVDg3umfdIkGSK9DA",
+ "width": 168,
+ "height": 94
+ },
+ "medium": {
+ "url": "https://i.ytimg.com/vi/4HsGaWqB20g/hqdefault.jpg?sqp=-oaymwEbCMQBEG5IVfKriqkDDggBFQAAiEIYAXABwAEG&rs=AOn4CLCYZTXyhn4GzF2eZ9g6b4V8NPPoXQ",
+ "width": 196,
+ "height": 110
+ },
+ "high": {
+ "url": "https://i.ytimg.com/vi/4HsGaWqB20g/hqdefault.jpg?sqp=-oaymwEcCPYBEIoBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==&rs=AOn4CLDz5ILcwZ34FmxKZQ9zE23YJvzY9Q",
+ "width": 246,
+ "height": 138
+ },
+ "standard": {
+ "url": "https://i.ytimg.com/vi/4HsGaWqB20g/hqdefault.jpg?sqp=-oaymwEcCNACELwBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==&rs=AOn4CLBFDJQzDFEnogWp7Scm5-v1-c0lDQ",
+ "width": 336,
+ "height": 188
+ }
+ }
+ },
+ {
+ "player": "youtube",
+ "id": "D2VqJesbL-E",
+ "title": "Métodos mágicos II (Rolando Caldas)",
+ "pubDate": null,
+ "thumbnails": {
+ "default": {
+ "url": "https://i.ytimg.com/vi/D2VqJesbL-E/hqdefault.jpg?sqp=-oaymwEbCKgBEF5IVfKriqkDDggBFQAAiEIYAXABwAEG&rs=AOn4CLCTjeV1yxWHD-g_6yqUEdfR2Ve3yg",
+ "width": 168,
+ "height": 94
+ },
+ "medium": {
+ "url": "https://i.ytimg.com/vi/D2VqJesbL-E/hqdefault.jpg?sqp=-oaymwEbCMQBEG5IVfKriqkDDggBFQAAiEIYAXABwAEG&rs=AOn4CLD7-a6rCGvk7B8EEZ5jqlBEfmBihA",
+ "width": 196,
+ "height": 110
+ },
+ "high": {
+ "url": "https://i.ytimg.com/vi/D2VqJesbL-E/hqdefault.jpg?sqp=-oaymwEcCPYBEIoBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==&rs=AOn4CLD-8vdJ4qnv29SNZHMMSdGTe7pL7A",
+ "width": 246,
+ "height": 138
+ },
+ "standard": {
+ "url": "https://i.ytimg.com/vi/D2VqJesbL-E/hqdefault.jpg?sqp=-oaymwEcCNACELwBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==&rs=AOn4CLB7tNmWlw0qpA_VDX8u1vbWJzb1Ww",
+ "width": 336,
+ "height": 188
+ }
+ }
+ },
+ {
+ "player": "youtube",
+ "id": "VVbdoCTiN44",
+ "title": "Shame on you PHP!! (Sergio Carracedo)",
+ "pubDate": null,
+ "thumbnails": {
+ "default": {
+ "url": "https://i.ytimg.com/vi/VVbdoCTiN44/hqdefault.jpg?sqp=-oaymwEbCKgBEF5IVfKriqkDDggBFQAAiEIYAXABwAEG&rs=AOn4CLCFcURvZdrrYbiGWpzwTMYRi8yhKw",
+ "width": 168,
+ "height": 94
+ },
+ "medium": {
+ "url": "https://i.ytimg.com/vi/VVbdoCTiN44/hqdefault.jpg?sqp=-oaymwEbCMQBEG5IVfKriqkDDggBFQAAiEIYAXABwAEG&rs=AOn4CLB6cxuAmZTgZmJXN7Q1xphxYxN3JQ",
+ "width": 196,
+ "height": 110
+ },
+ "high": {
+ "url": "https://i.ytimg.com/vi/VVbdoCTiN44/hqdefault.jpg?sqp=-oaymwEcCPYBEIoBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==&rs=AOn4CLBiXm4eJZbeX36SC3VCETy-Cw5Gtw",
+ "width": 246,
+ "height": 138
+ },
+ "standard": {
+ "url": "https://i.ytimg.com/vi/VVbdoCTiN44/hqdefault.jpg?sqp=-oaymwEcCNACELwBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==&rs=AOn4CLAyWU65eV2OHnLt3U1waP5U1762Bw",
+ "width": 336,
+ "height": 188
+ }
+ }
+ },
+ {
+ "player": "youtube",
+ "id": "yzoyQg1NIRo",
+ "title": "PHP Traits (Carlos Goce)",
+ "pubDate": null,
+ "thumbnails": {
+ "default": {
+ "url": "https://i.ytimg.com/vi/yzoyQg1NIRo/hqdefault.jpg?sqp=-oaymwEbCKgBEF5IVfKriqkDDggBFQAAiEIYAXABwAEG&rs=AOn4CLAZilRq4pRcP96gs9l2rOMT86YepQ",
+ "width": 168,
+ "height": 94
+ },
+ "medium": {
+ "url": "https://i.ytimg.com/vi/yzoyQg1NIRo/hqdefault.jpg?sqp=-oaymwEbCMQBEG5IVfKriqkDDggBFQAAiEIYAXABwAEG&rs=AOn4CLB7lZq9EDMhI2Pt2X5AoeRJptI0SQ",
+ "width": 196,
+ "height": 110
+ },
+ "high": {
+ "url": "https://i.ytimg.com/vi/yzoyQg1NIRo/hqdefault.jpg?sqp=-oaymwEcCPYBEIoBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==&rs=AOn4CLBG28rhQlXtacXH-KLvd5MPhP4sEA",
+ "width": 246,
+ "height": 138
+ },
+ "standard": {
+ "url": "https://i.ytimg.com/vi/yzoyQg1NIRo/hqdefault.jpg?sqp=-oaymwEcCNACELwBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==&rs=AOn4CLAZleBtC8u2W2mOjO3IJgk_VxOiSA",
+ "width": 336,
+ "height": 188
+ }
+ }
+ },
+ {
+ "player": "youtube",
+ "id": "TuGZWmsf-Mk",
+ "title": "Meetup #12: \"Performance blackfire.io\"",
+ "pubDate": null,
+ "thumbnails": {
+ "default": {
+ "url": "https://i.ytimg.com/vi/TuGZWmsf-Mk/hqdefault.jpg?sqp=-oaymwEbCKgBEF5IVfKriqkDDggBFQAAiEIYAXABwAEG&rs=AOn4CLAeGjVwWwU3DNebAdFLvtxeX_nDig",
+ "width": 168,
+ "height": 94
+ },
+ "medium": {
+ "url": "https://i.ytimg.com/vi/TuGZWmsf-Mk/hqdefault.jpg?sqp=-oaymwEbCMQBEG5IVfKriqkDDggBFQAAiEIYAXABwAEG&rs=AOn4CLAQ1vyh3VMBEGCXcccsdWSVGUzrTg",
+ "width": 196,
+ "height": 110
+ },
+ "high": {
+ "url": "https://i.ytimg.com/vi/TuGZWmsf-Mk/hqdefault.jpg?sqp=-oaymwEcCPYBEIoBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==&rs=AOn4CLCc_GuljhqKErXcoaW-K6qZPaYVZw",
+ "width": 246,
+ "height": 138
+ },
+ "standard": {
+ "url": "https://i.ytimg.com/vi/TuGZWmsf-Mk/hqdefault.jpg?sqp=-oaymwEcCNACELwBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==&rs=AOn4CLDCaZxqEl9FVN2vSFBBWxiX9BUkLA",
+ "width": 336,
+ "height": 188
+ }
+ }
+ },
+ {
+ "player": "youtube",
+ "id": "wyLUeXr7v_M",
+ "title": "Meetup #12: \"Gestionar un WP con 250k pv diarias\"",
+ "pubDate": null,
+ "thumbnails": {
+ "default": {
+ "url": "https://i.ytimg.com/vi/wyLUeXr7v_M/hqdefault.jpg?sqp=-oaymwEbCKgBEF5IVfKriqkDDggBFQAAiEIYAXABwAEG&rs=AOn4CLDjFfbUPh7wMS_qdh-nQg6K3af4sg",
+ "width": 168,
+ "height": 94
+ },
+ "medium": {
+ "url": "https://i.ytimg.com/vi/wyLUeXr7v_M/hqdefault.jpg?sqp=-oaymwEbCMQBEG5IVfKriqkDDggBFQAAiEIYAXABwAEG&rs=AOn4CLAY73DpQAcXY8mscVhJ_07blpCF6w",
+ "width": 196,
+ "height": 110
+ },
+ "high": {
+ "url": "https://i.ytimg.com/vi/wyLUeXr7v_M/hqdefault.jpg?sqp=-oaymwEcCPYBEIoBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==&rs=AOn4CLBtkYhw2pgVaqoxMfGaPrMc4u9K0A",
+ "width": 246,
+ "height": 138
+ },
+ "standard": {
+ "url": "https://i.ytimg.com/vi/wyLUeXr7v_M/hqdefault.jpg?sqp=-oaymwEcCNACELwBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==&rs=AOn4CLDR5EKmJtp6J6r5fuK0AZdg7OxliQ",
+ "width": 336,
+ "height": 188
+ }
+ }
+ },
+ {
+ "player": "youtube",
+ "id": "ylWJ3n6HJXY",
+ "title": "2017 03 22 21 26 38",
+ "pubDate": null,
+ "thumbnails": {
+ "default": {
+ "url": "https://i.ytimg.com/vi/ylWJ3n6HJXY/hqdefault.jpg?sqp=-oaymwEbCKgBEF5IVfKriqkDDggBFQAAiEIYAXABwAEG&rs=AOn4CLCXl1O3KkZnm1gTkB6UtAxAgeOG-Q",
+ "width": 168,
+ "height": 94
+ },
+ "medium": {
+ "url": "https://i.ytimg.com/vi/ylWJ3n6HJXY/hqdefault.jpg?sqp=-oaymwEbCMQBEG5IVfKriqkDDggBFQAAiEIYAXABwAEG&rs=AOn4CLCW9uZJm2G_tT4O-pdS97p9BH2nGA",
+ "width": 196,
+ "height": 110
+ },
+ "high": {
+ "url": "https://i.ytimg.com/vi/ylWJ3n6HJXY/hqdefault.jpg?sqp=-oaymwEcCPYBEIoBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==&rs=AOn4CLBItDOCm4cFE0eVI3SuVBzROUOX2Q",
+ "width": 246,
+ "height": 138
+ },
+ "standard": {
+ "url": "https://i.ytimg.com/vi/ylWJ3n6HJXY/hqdefault.jpg?sqp=-oaymwEcCNACELwBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==&rs=AOn4CLBVIj8MrW35EvNS8tQz-9s84RiBuQ",
+ "width": 336,
+ "height": 188
+ }
+ }
+ },
+ {
+ "player": "youtube",
+ "id": "304IKjdiDG8",
+ "title": "Zend Certified Engineer (Orestes Carracedo)",
+ "pubDate": null,
+ "thumbnails": {
+ "default": {
+ "url": "https://i.ytimg.com/vi/304IKjdiDG8/hqdefault.jpg?sqp=-oaymwEbCKgBEF5IVfKriqkDDggBFQAAiEIYAXABwAEG&rs=AOn4CLAAb9306SN8an8XEYr95DPw9iBX9g",
+ "width": 168,
+ "height": 94
+ },
+ "medium": {
+ "url": "https://i.ytimg.com/vi/304IKjdiDG8/hqdefault.jpg?sqp=-oaymwEbCMQBEG5IVfKriqkDDggBFQAAiEIYAXABwAEG&rs=AOn4CLAyubyw1SKOmqM_VPYf9WsEJnbtsg",
+ "width": 196,
+ "height": 110
+ },
+ "high": {
+ "url": "https://i.ytimg.com/vi/304IKjdiDG8/hqdefault.jpg?sqp=-oaymwEcCPYBEIoBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==&rs=AOn4CLBZrIHgVdkilJSSA-uxNiWzQKNOQQ",
+ "width": 246,
+ "height": 138
+ },
+ "standard": {
+ "url": "https://i.ytimg.com/vi/304IKjdiDG8/hqdefault.jpg?sqp=-oaymwEcCNACELwBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==&rs=AOn4CLDJiDt-L2tzofwB7f9gMR76aLW02Q",
+ "width": 336,
+ "height": 188
+ }
+ }
+ },
+ {
+ "player": "youtube",
+ "id": "GIbQYfj2K5g",
+ "title": "Blackfire.io: Mide tu performance (Ruben Gonzalez)",
+ "pubDate": null,
+ "thumbnails": {
+ "default": {
+ "url": "https://i.ytimg.com/vi/GIbQYfj2K5g/hqdefault.jpg?sqp=-oaymwEbCKgBEF5IVfKriqkDDggBFQAAiEIYAXABwAEG&rs=AOn4CLBSeGoO9vvTsEM9sQX4nI5hT6m6hw",
+ "width": 168,
+ "height": 94
+ },
+ "medium": {
+ "url": "https://i.ytimg.com/vi/GIbQYfj2K5g/hqdefault.jpg?sqp=-oaymwEbCMQBEG5IVfKriqkDDggBFQAAiEIYAXABwAEG&rs=AOn4CLCWzsYDUBD2RQFLkWH1i5OipZGYag",
+ "width": 196,
+ "height": 110
+ },
+ "high": {
+ "url": "https://i.ytimg.com/vi/GIbQYfj2K5g/hqdefault.jpg?sqp=-oaymwEcCPYBEIoBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==&rs=AOn4CLAAghlZE6Eg7Gchj221RwBK5yfI9w",
+ "width": 246,
+ "height": 138
+ },
+ "standard": {
+ "url": "https://i.ytimg.com/vi/GIbQYfj2K5g/hqdefault.jpg?sqp=-oaymwEcCNACELwBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==&rs=AOn4CLAVU5Obcrrg3DvXxW6HFOaoOENIaA",
+ "width": 336,
+ "height": 188
+ }
+ }
+ },
+ {
+ "player": "youtube",
+ "id": "nxKtcLQl-OY",
+ "title": "Resque: Workers Asíncronos (Sergio Carracedo)",
+ "pubDate": null,
+ "thumbnails": {
+ "default": {
+ "url": "https://i.ytimg.com/vi/nxKtcLQl-OY/hqdefault.jpg?sqp=-oaymwEbCKgBEF5IVfKriqkDDggBFQAAiEIYAXABwAEG&rs=AOn4CLDfR2e2XZUlKaV0Rb_jO82fLwi06w",
+ "width": 168,
+ "height": 94
+ },
+ "medium": {
+ "url": "https://i.ytimg.com/vi/nxKtcLQl-OY/hqdefault.jpg?sqp=-oaymwEbCMQBEG5IVfKriqkDDggBFQAAiEIYAXABwAEG&rs=AOn4CLDYQrHkkFin_hmxYVZ_BtdSceCUug",
+ "width": 196,
+ "height": 110
+ },
+ "high": {
+ "url": "https://i.ytimg.com/vi/nxKtcLQl-OY/hqdefault.jpg?sqp=-oaymwEcCPYBEIoBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==&rs=AOn4CLBtKvJZA-9h4MOAOwurInXPjI1hpQ",
+ "width": 246,
+ "height": 138
+ },
+ "standard": {
+ "url": "https://i.ytimg.com/vi/nxKtcLQl-OY/hqdefault.jpg?sqp=-oaymwEcCNACELwBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==&rs=AOn4CLC-_AR9NEW52Z81WzNnRE_Q6Cb85Q",
+ "width": 336,
+ "height": 188
+ }
+ }
+ },
+ {
+ "player": "youtube",
+ "id": "Dz8giDh9j9k",
+ "title": "Métodos mágicos (Rolando Caldas Sánchez)",
+ "pubDate": null,
+ "thumbnails": {
+ "default": {
+ "url": "https://i.ytimg.com/vi/Dz8giDh9j9k/hqdefault.jpg?sqp=-oaymwEbCKgBEF5IVfKriqkDDggBFQAAiEIYAXABwAEG&rs=AOn4CLBWaSuPDOdn_yzNAU7X5_VLad_JvQ",
+ "width": 168,
+ "height": 94
+ },
+ "medium": {
+ "url": "https://i.ytimg.com/vi/Dz8giDh9j9k/hqdefault.jpg?sqp=-oaymwEbCMQBEG5IVfKriqkDDggBFQAAiEIYAXABwAEG&rs=AOn4CLDSiWSvZhRvyx63GxteDjdEHyZPEw",
+ "width": 196,
+ "height": 110
+ },
+ "high": {
+ "url": "https://i.ytimg.com/vi/Dz8giDh9j9k/hqdefault.jpg?sqp=-oaymwEcCPYBEIoBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==&rs=AOn4CLCTCmgBaHr782pNXm7De1a7G_KlRg",
+ "width": 246,
+ "height": 138
+ },
+ "standard": {
+ "url": "https://i.ytimg.com/vi/Dz8giDh9j9k/hqdefault.jpg?sqp=-oaymwEcCNACELwBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==&rs=AOn4CLAGC99y4ElqX160PzN3yGaYus_ZbQ",
+ "width": 336,
+ "height": 188
+ }
+ }
+ },
+ {
+ "player": "youtube",
+ "id": "fZxGpE6ki3g",
+ "title": "Conectar a MySQL correctamente (Jose Antonio González López)",
+ "pubDate": null,
+ "thumbnails": {
+ "default": {
+ "url": "https://i.ytimg.com/vi/fZxGpE6ki3g/hqdefault.jpg?sqp=-oaymwEbCKgBEF5IVfKriqkDDggBFQAAiEIYAXABwAEG&rs=AOn4CLA_YwdVtojNjgNe4CYLFJV3p0fYGw",
+ "width": 168,
+ "height": 94
+ },
+ "medium": {
+ "url": "https://i.ytimg.com/vi/fZxGpE6ki3g/hqdefault.jpg?sqp=-oaymwEbCMQBEG5IVfKriqkDDggBFQAAiEIYAXABwAEG&rs=AOn4CLAMGdohTzFJeNXszjxz-m76tigrgg",
+ "width": 196,
+ "height": 110
+ },
+ "high": {
+ "url": "https://i.ytimg.com/vi/fZxGpE6ki3g/hqdefault.jpg?sqp=-oaymwEcCPYBEIoBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==&rs=AOn4CLAw26EU3ytUlMDyn-LvjIPczPnQEw",
+ "width": 246,
+ "height": 138
+ },
+ "standard": {
+ "url": "https://i.ytimg.com/vi/fZxGpE6ki3g/hqdefault.jpg?sqp=-oaymwEcCNACELwBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==&rs=AOn4CLDxJjS-R39TORUJb-6cBUfDcobVKQ",
+ "width": 336,
+ "height": 188
+ }
+ }
+ },
+ {
+ "player": "youtube",
+ "id": "ZIX6z-xYN90",
+ "title": "Jenkins: Deja ya de hacerlo a mano!\" - Santiago Rodriguez Collazo",
+ "pubDate": null,
+ "thumbnails": {
+ "default": {
+ "url": "https://i.ytimg.com/vi/ZIX6z-xYN90/hqdefault.jpg?sqp=-oaymwEbCKgBEF5IVfKriqkDDggBFQAAiEIYAXABwAEG&rs=AOn4CLC6bndimvpyZ5Ab8-5OsjgRLWhmMQ",
+ "width": 168,
+ "height": 94
+ },
+ "medium": {
+ "url": "https://i.ytimg.com/vi/ZIX6z-xYN90/hqdefault.jpg?sqp=-oaymwEbCMQBEG5IVfKriqkDDggBFQAAiEIYAXABwAEG&rs=AOn4CLCsASMmU2zIwwZxw2UQ8l_QbL2VCA",
+ "width": 196,
+ "height": 110
+ },
+ "high": {
+ "url": "https://i.ytimg.com/vi/ZIX6z-xYN90/hqdefault.jpg?sqp=-oaymwEcCPYBEIoBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==&rs=AOn4CLAnNnOlvRWPjRRKCsr4gIAHzAo0Mw",
+ "width": 246,
+ "height": 138
+ },
+ "standard": {
+ "url": "https://i.ytimg.com/vi/ZIX6z-xYN90/hqdefault.jpg?sqp=-oaymwEcCNACELwBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==&rs=AOn4CLASjqzUD7KkZyOiE0uasojGW6SVyw",
+ "width": 336,
+ "height": 188
+ }
+ }
+ },
+ {
+ "player": "youtube",
+ "id": "LOQ7zTWD5tI",
+ "title": "Arrays y Js, vamos a jugar - David García (@tansitos)",
+ "pubDate": null,
+ "thumbnails": {
+ "default": {
+ "url": "https://i.ytimg.com/vi/LOQ7zTWD5tI/hqdefault.jpg?sqp=-oaymwEbCKgBEF5IVfKriqkDDggBFQAAiEIYAXABwAEG&rs=AOn4CLA-vPyj0jS2ahb4icRE5HY2VfGNKA",
+ "width": 168,
+ "height": 94
+ },
+ "medium": {
+ "url": "https://i.ytimg.com/vi/LOQ7zTWD5tI/hqdefault.jpg?sqp=-oaymwEbCMQBEG5IVfKriqkDDggBFQAAiEIYAXABwAEG&rs=AOn4CLDonLZPTBas-5O4KJsKD-jsXGWeHA",
+ "width": 196,
+ "height": 110
+ },
+ "high": {
+ "url": "https://i.ytimg.com/vi/LOQ7zTWD5tI/hqdefault.jpg?sqp=-oaymwEcCPYBEIoBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==&rs=AOn4CLBd2yQuOXIs6NmPtU2SDhOFzU1xAw",
+ "width": 246,
+ "height": 138
+ },
+ "standard": {
+ "url": "https://i.ytimg.com/vi/LOQ7zTWD5tI/hqdefault.jpg?sqp=-oaymwEcCNACELwBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==&rs=AOn4CLCuB-wsXHuzdqifnmuonX1-ZinHag",
+ "width": 336,
+ "height": 188
+ }
+ }
+ },
+ {
+ "player": "youtube",
+ "id": "cB3fHLy1Sc4",
+ "title": "Postgresql 101 - Eloy Coto (@eloycoto)",
+ "pubDate": null,
+ "thumbnails": {
+ "default": {
+ "url": "https://i.ytimg.com/vi/cB3fHLy1Sc4/hqdefault.jpg?sqp=-oaymwEbCKgBEF5IVfKriqkDDggBFQAAiEIYAXABwAEG&rs=AOn4CLCXH9vNG5PrWqgDzddLb600Phw0Pg",
+ "width": 168,
+ "height": 94
+ },
+ "medium": {
+ "url": "https://i.ytimg.com/vi/cB3fHLy1Sc4/hqdefault.jpg?sqp=-oaymwEbCMQBEG5IVfKriqkDDggBFQAAiEIYAXABwAEG&rs=AOn4CLDnQAbtdDeMuJzY0hehlGCb4QoIDw",
+ "width": 196,
+ "height": 110
+ },
+ "high": {
+ "url": "https://i.ytimg.com/vi/cB3fHLy1Sc4/hqdefault.jpg?sqp=-oaymwEcCPYBEIoBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==&rs=AOn4CLC8OfCMsy5W1E0RYYx13p2g-D7Dwg",
+ "width": 246,
+ "height": 138
+ },
+ "standard": {
+ "url": "https://i.ytimg.com/vi/cB3fHLy1Sc4/hqdefault.jpg?sqp=-oaymwEcCNACELwBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==&rs=AOn4CLDSW7RZ-5Js3SRGx_DRhD_DOmVFNA",
+ "width": 336,
+ "height": 188
+ }
+ }
+ },
+ {
+ "player": "youtube",
+ "id": "UhPfaMEWHDs",
+ "title": "Preprocesadores CSS",
+ "pubDate": null,
+ "thumbnails": {
+ "default": {
+ "url": "https://i.ytimg.com/vi/UhPfaMEWHDs/hqdefault.jpg?sqp=-oaymwEbCKgBEF5IVfKriqkDDggBFQAAiEIYAXABwAEG&rs=AOn4CLBvtgyGCeB4sbluYTWouU35Es6FFQ",
+ "width": 168,
+ "height": 94
+ },
+ "medium": {
+ "url": "https://i.ytimg.com/vi/UhPfaMEWHDs/hqdefault.jpg?sqp=-oaymwEbCMQBEG5IVfKriqkDDggBFQAAiEIYAXABwAEG&rs=AOn4CLCoU5FlrEQxK43xHWZw4asIOC0drg",
+ "width": 196,
+ "height": 110
+ },
+ "high": {
+ "url": "https://i.ytimg.com/vi/UhPfaMEWHDs/hqdefault.jpg?sqp=-oaymwEcCPYBEIoBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==&rs=AOn4CLBFeRZ42mKRcc3Gs49vxwHMb6bTGQ",
+ "width": 246,
+ "height": 138
+ },
+ "standard": {
+ "url": "https://i.ytimg.com/vi/UhPfaMEWHDs/hqdefault.jpg?sqp=-oaymwEcCNACELwBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==&rs=AOn4CLCbBta5JoI1D297F15UgveADFbILg",
+ "width": 336,
+ "height": 188
+ }
+ }
+ },
+ {
+ "player": "youtube",
+ "id": "LVK88Gcu7-Q",
+ "title": "Preprocesadores CSS",
+ "pubDate": null,
+ "thumbnails": {
+ "default": {
+ "url": "https://i.ytimg.com/vi/LVK88Gcu7-Q/hqdefault.jpg?sqp=-oaymwEbCKgBEF5IVfKriqkDDggBFQAAiEIYAXABwAEG&rs=AOn4CLDEHg8v05HggZjroXNUxjR5jxGWxw",
+ "width": 168,
+ "height": 94
+ },
+ "medium": {
+ "url": "https://i.ytimg.com/vi/LVK88Gcu7-Q/hqdefault.jpg?sqp=-oaymwEbCMQBEG5IVfKriqkDDggBFQAAiEIYAXABwAEG&rs=AOn4CLAdz25okRNyJ88XALCLMNyPu2qjpw",
+ "width": 196,
+ "height": 110
+ },
+ "high": {
+ "url": "https://i.ytimg.com/vi/LVK88Gcu7-Q/hqdefault.jpg?sqp=-oaymwEcCPYBEIoBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==&rs=AOn4CLDFt84O3mYEibVjArtXG1y1uFhO0g",
+ "width": 246,
+ "height": 138
+ },
+ "standard": {
+ "url": "https://i.ytimg.com/vi/LVK88Gcu7-Q/hqdefault.jpg?sqp=-oaymwEcCNACELwBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==&rs=AOn4CLAZxyQEVNAVB5ZpfCCQTWS0nP8X0Q",
+ "width": 336,
+ "height": 188
+ }
+ }
+ },
+ {
+ "player": "youtube",
+ "id": "uDzna9mbIBw",
+ "title": "\"API REST\" - Bueno Bonito Barato",
+ "pubDate": null,
+ "thumbnails": {
+ "default": {
+ "url": "https://i.ytimg.com/vi/uDzna9mbIBw/hqdefault.jpg?sqp=-oaymwEbCKgBEF5IVfKriqkDDggBFQAAiEIYAXABwAEG&rs=AOn4CLBMOb5vtBlAb6ERLddOjShFEXLB4A",
+ "width": 168,
+ "height": 94
+ },
+ "medium": {
+ "url": "https://i.ytimg.com/vi/uDzna9mbIBw/hqdefault.jpg?sqp=-oaymwEbCMQBEG5IVfKriqkDDggBFQAAiEIYAXABwAEG&rs=AOn4CLD9cW1A0Wdmy1HTHuz3DiqWK4a0Bg",
+ "width": 196,
+ "height": 110
+ },
+ "high": {
+ "url": "https://i.ytimg.com/vi/uDzna9mbIBw/hqdefault.jpg?sqp=-oaymwEcCPYBEIoBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==&rs=AOn4CLDX5bjOk9RaUuww0ApiTjx9MxFdhw",
+ "width": 246,
+ "height": 138
+ },
+ "standard": {
+ "url": "https://i.ytimg.com/vi/uDzna9mbIBw/hqdefault.jpg?sqp=-oaymwEcCNACELwBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==&rs=AOn4CLD87rlezpeLJjb4jf7F_7soXEt8rQ",
+ "width": 336,
+ "height": 188
+ }
+ }
+ },
+ {
+ "player": "youtube",
+ "id": "q4Vl54AsnaI",
+ "title": "Felicitacion PHPVigo 2016",
+ "pubDate": null,
+ "thumbnails": {
+ "default": {
+ "url": "https://i.ytimg.com/vi/q4Vl54AsnaI/hqdefault.jpg?sqp=-oaymwEbCKgBEF5IVfKriqkDDggBFQAAiEIYAXABwAEG&rs=AOn4CLCG0eXa91PlRLTuEDdgpADAykXs0A",
+ "width": 168,
+ "height": 94
+ },
+ "medium": {
+ "url": "https://i.ytimg.com/vi/q4Vl54AsnaI/hqdefault.jpg?sqp=-oaymwEbCMQBEG5IVfKriqkDDggBFQAAiEIYAXABwAEG&rs=AOn4CLA1UDRzzRRAp0M0DNbfXLvkV7f_aQ",
+ "width": 196,
+ "height": 110
+ },
+ "high": {
+ "url": "https://i.ytimg.com/vi/q4Vl54AsnaI/hqdefault.jpg?sqp=-oaymwEcCPYBEIoBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==&rs=AOn4CLAg5GrS6cdwHoSAHklc7uWBcZX93A",
+ "width": 246,
+ "height": 138
+ },
+ "standard": {
+ "url": "https://i.ytimg.com/vi/q4Vl54AsnaI/hqdefault.jpg?sqp=-oaymwEcCNACELwBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==&rs=AOn4CLCwCw6I-BJMSiuQIGb4avXBV2gFgw",
+ "width": 336,
+ "height": 188
+ }
+ }
+ },
+ {
+ "player": "youtube",
+ "id": "KOJcOyySPRM",
+ "title": "Dónde está mi ñ",
+ "pubDate": null,
+ "thumbnails": {
+ "default": {
+ "url": "https://i.ytimg.com/vi/KOJcOyySPRM/hqdefault.jpg?sqp=-oaymwEbCKgBEF5IVfKriqkDDggBFQAAiEIYAXABwAEG&rs=AOn4CLCNN47hFjgbYz-AegO3O77OauMYHA",
+ "width": 168,
+ "height": 94
+ },
+ "medium": {
+ "url": "https://i.ytimg.com/vi/KOJcOyySPRM/hqdefault.jpg?sqp=-oaymwEbCMQBEG5IVfKriqkDDggBFQAAiEIYAXABwAEG&rs=AOn4CLBi72RRKrKeyezwUsEotmeFKCLfhg",
+ "width": 196,
+ "height": 110
+ },
+ "high": {
+ "url": "https://i.ytimg.com/vi/KOJcOyySPRM/hqdefault.jpg?sqp=-oaymwEcCPYBEIoBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==&rs=AOn4CLBdefbzzLboA6rBpatopmfL6Fpg-A",
+ "width": 246,
+ "height": 138
+ },
+ "standard": {
+ "url": "https://i.ytimg.com/vi/KOJcOyySPRM/hqdefault.jpg?sqp=-oaymwEcCNACELwBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==&rs=AOn4CLBg70H4Q6gX7gdFRWKK5G-QybgAVg",
+ "width": 336,
+ "height": 188
+ }
+ }
+ },
+ {
+ "player": "youtube",
+ "id": "bteb03R2hpo",
+ "title": "Dónde está mi ñ\" -Miguel Gonzalez (@migonzalvar)",
+ "pubDate": null,
+ "thumbnails": {
+ "default": {
+ "url": "https://i.ytimg.com/vi/bteb03R2hpo/hqdefault.jpg?sqp=-oaymwEbCKgBEF5IVfKriqkDDggBFQAAiEIYAXABwAEG&rs=AOn4CLD-xwlHxI1EmpimZOSVwah0DUN4cA",
+ "width": 168,
+ "height": 94
+ },
+ "medium": {
+ "url": "https://i.ytimg.com/vi/bteb03R2hpo/hqdefault.jpg?sqp=-oaymwEbCMQBEG5IVfKriqkDDggBFQAAiEIYAXABwAEG&rs=AOn4CLAqVkoESCKXUktHvDPh2ppC4egYRw",
+ "width": 196,
+ "height": 110
+ },
+ "high": {
+ "url": "https://i.ytimg.com/vi/bteb03R2hpo/hqdefault.jpg?sqp=-oaymwEcCPYBEIoBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==&rs=AOn4CLCeeZz_KbvgryCcL5PzXd22mWuy4w",
+ "width": 246,
+ "height": 138
+ },
+ "standard": {
+ "url": "https://i.ytimg.com/vi/bteb03R2hpo/hqdefault.jpg?sqp=-oaymwEcCNACELwBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==&rs=AOn4CLAEhHaRceJ0ItLulnYYNkFNf9KAAA",
+ "width": 336,
+ "height": 188
+ }
+ }
+ },
+ {
+ "player": "youtube",
+ "id": "ScLGm6jitik",
+ "title": "Meetup#7: AWS Reload y Despliegue con Deployer",
+ "pubDate": null,
+ "thumbnails": {
+ "default": {
+ "url": "https://i.ytimg.com/vi/ScLGm6jitik/hqdefault.jpg?sqp=-oaymwE1CKgBEF5IVfKriqkDKAgBFQAAiEIYAXABwAEG8AEB-AH-CYAC0AWKAgwIABABGEQgUyhyMA8=&rs=AOn4CLDfMGz-ZxDyqYkxL1CV2LYX1b8zsw",
+ "width": 168,
+ "height": 94
+ },
+ "medium": {
+ "url": "https://i.ytimg.com/vi/ScLGm6jitik/hqdefault.jpg?sqp=-oaymwE1CMQBEG5IVfKriqkDKAgBFQAAiEIYAXABwAEG8AEB-AH-CYAC0AWKAgwIABABGEQgUyhyMA8=&rs=AOn4CLBKUPxCvTYRafUN6v8kM3vWaQ9ZKQ",
+ "width": 196,
+ "height": 110
+ },
+ "high": {
+ "url": "https://i.ytimg.com/vi/ScLGm6jitik/hqdefault.jpg?sqp=-oaymwE2CPYBEIoBSFXyq4qpAygIARUAAIhCGAFwAcABBvABAfgB_gmAAtAFigIMCAAQARhEIFMocjAP&rs=AOn4CLAQ44fSWoqu6picqTk5gq1y_-2lUA",
+ "width": 246,
+ "height": 138
+ },
+ "standard": {
+ "url": "https://i.ytimg.com/vi/ScLGm6jitik/hqdefault.jpg?sqp=-oaymwE2CNACELwBSFXyq4qpAygIARUAAIhCGAFwAcABBvABAfgB_gmAAtAFigIMCAAQARhEIFMocjAP&rs=AOn4CLCY7Abq3mniZSvU5kb4g6WvGOwcMg",
+ "width": 336,
+ "height": 188
+ }
+ }
+ },
+ {
+ "player": "youtube",
+ "id": "svqEwpbjkvA",
+ "title": "¿Nos hacen los tests ir más rápidos?",
+ "pubDate": null,
+ "thumbnails": {
+ "default": {
+ "url": "https://i.ytimg.com/vi/svqEwpbjkvA/hqdefault.jpg?sqp=-oaymwE1CKgBEF5IVfKriqkDKAgBFQAAiEIYAXABwAEG8AEB-AH-CYAC0AWKAgwIABABGH8gOSgTMA8=&rs=AOn4CLCk6bqJEZlvpiLBbDW98_do18I9aQ",
+ "width": 168,
+ "height": 94
+ },
+ "medium": {
+ "url": "https://i.ytimg.com/vi/svqEwpbjkvA/hqdefault.jpg?sqp=-oaymwE1CMQBEG5IVfKriqkDKAgBFQAAiEIYAXABwAEG8AEB-AH-CYAC0AWKAgwIABABGH8gOSgTMA8=&rs=AOn4CLAjKrR7K3VpH4nzUR2MSZYdbIOR-A",
+ "width": 196,
+ "height": 110
+ },
+ "high": {
+ "url": "https://i.ytimg.com/vi/svqEwpbjkvA/hqdefault.jpg?sqp=-oaymwE2CPYBEIoBSFXyq4qpAygIARUAAIhCGAFwAcABBvABAfgB_gmAAtAFigIMCAAQARh_IDkoEzAP&rs=AOn4CLB8JYT9joyBO19wa9CC0N_x1BkOjg",
+ "width": 246,
+ "height": 138
+ },
+ "standard": {
+ "url": "https://i.ytimg.com/vi/svqEwpbjkvA/hqdefault.jpg?sqp=-oaymwE2CNACELwBSFXyq4qpAygIARUAAIhCGAFwAcABBvABAfgB_gmAAtAFigIMCAAQARh_IDkoEzAP&rs=AOn4CLBJSPaM_1TNibmEgwPElFJo7wNwlw",
+ "width": 336,
+ "height": 188
+ }
+ }
+ },
+ {
+ "player": "youtube",
+ "id": "rffMsQRFml8",
+ "title": "phpVigo AWS",
+ "pubDate": null,
+ "thumbnails": {
+ "default": {
+ "url": "https://i.ytimg.com/vi/rffMsQRFml8/hqdefault.jpg?sqp=-oaymwEbCKgBEF5IVfKriqkDDggBFQAAiEIYAXABwAEG&rs=AOn4CLA5S-QT4gcbmy3fAS_mSf_ztH-zAA",
+ "width": 168,
+ "height": 94
+ },
+ "medium": {
+ "url": "https://i.ytimg.com/vi/rffMsQRFml8/hqdefault.jpg?sqp=-oaymwEbCMQBEG5IVfKriqkDDggBFQAAiEIYAXABwAEG&rs=AOn4CLCssn1vnCCKEGXYFDMoAjVXL84t8w",
+ "width": 196,
+ "height": 110
+ },
+ "high": {
+ "url": "https://i.ytimg.com/vi/rffMsQRFml8/hqdefault.jpg?sqp=-oaymwEcCPYBEIoBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==&rs=AOn4CLCiMhrWlALdAaejRqRlCSo3QhBLTg",
+ "width": 246,
+ "height": 138
+ },
+ "standard": {
+ "url": "https://i.ytimg.com/vi/rffMsQRFml8/hqdefault.jpg?sqp=-oaymwEcCNACELwBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==&rs=AOn4CLA0iJJ2Tl9zoTNom4Vysl1U4yumtQ",
+ "width": 336,
+ "height": 188
+ }
+ }
+ },
+ {
+ "player": "youtube",
+ "id": "Nkrt5d_jZtI",
+ "title": "PHPVigo Drupal",
+ "pubDate": null,
+ "thumbnails": {
+ "default": {
+ "url": "https://i.ytimg.com/vi/Nkrt5d_jZtI/hqdefault.jpg?sqp=-oaymwE1CKgBEF5IVfKriqkDKAgBFQAAiEIYAXABwAEG8AEB-AH-CYAC0AWKAgwIABABGE0gPyh_MA8=&rs=AOn4CLA9kxyH09GO4JWu4wqy6IY4C-iXwQ",
+ "width": 168,
+ "height": 94
+ },
+ "medium": {
+ "url": "https://i.ytimg.com/vi/Nkrt5d_jZtI/hqdefault.jpg?sqp=-oaymwE1CMQBEG5IVfKriqkDKAgBFQAAiEIYAXABwAEG8AEB-AH-CYAC0AWKAgwIABABGE0gPyh_MA8=&rs=AOn4CLB-HlIurIpD__kkEfqEUdn9NGfJNQ",
+ "width": 196,
+ "height": 110
+ },
+ "high": {
+ "url": "https://i.ytimg.com/vi/Nkrt5d_jZtI/hqdefault.jpg?sqp=-oaymwE2CPYBEIoBSFXyq4qpAygIARUAAIhCGAFwAcABBvABAfgB_gmAAtAFigIMCAAQARhNID8ofzAP&rs=AOn4CLAhNutkXiWGpnSvbCjPfh_M5EpceA",
+ "width": 246,
+ "height": 138
+ },
+ "standard": {
+ "url": "https://i.ytimg.com/vi/Nkrt5d_jZtI/hqdefault.jpg?sqp=-oaymwE2CNACELwBSFXyq4qpAygIARUAAIhCGAFwAcABBvABAfgB_gmAAtAFigIMCAAQARhNID8ofzAP&rs=AOn4CLDHkC74CJZAyeCbHjGJXkwxNuPpCg",
+ "width": 336,
+ "height": 188
+ }
+ }
+ },
+ {
+ "player": "youtube",
+ "id": "o8_24tjP-2o",
+ "title": "Charla Introducción a Joomla por Pablo Arias - #PHPVigo Meetup #2",
+ "pubDate": null,
+ "thumbnails": {
+ "default": {
+ "url": "https://i.ytimg.com/vi/o8_24tjP-2o/hqdefault.jpg?sqp=-oaymwE1CKgBEF5IVfKriqkDKAgBFQAAiEIYAXABwAEG8AEB-AH-CYAC0AWKAgwIABABGHIgTSgwMA8=&rs=AOn4CLCnWHwaz_5tL7L6sH3M_hBM8lK0dw",
+ "width": 168,
+ "height": 94
+ },
+ "medium": {
+ "url": "https://i.ytimg.com/vi/o8_24tjP-2o/hqdefault.jpg?sqp=-oaymwE1CMQBEG5IVfKriqkDKAgBFQAAiEIYAXABwAEG8AEB-AH-CYAC0AWKAgwIABABGHIgTSgwMA8=&rs=AOn4CLDgcr0OAOLI2_AAKhFu9sLJYjz0fg",
+ "width": 196,
+ "height": 110
+ },
+ "high": {
+ "url": "https://i.ytimg.com/vi/o8_24tjP-2o/hqdefault.jpg?sqp=-oaymwE2CPYBEIoBSFXyq4qpAygIARUAAIhCGAFwAcABBvABAfgB_gmAAtAFigIMCAAQARhyIE0oMDAP&rs=AOn4CLDb5-iIuyBgm7hBO0prz9FfX7BaXA",
+ "width": 246,
+ "height": 138
+ },
+ "standard": {
+ "url": "https://i.ytimg.com/vi/o8_24tjP-2o/hqdefault.jpg?sqp=-oaymwE2CNACELwBSFXyq4qpAygIARUAAIhCGAFwAcABBvABAfgB_gmAAtAFigIMCAAQARhyIE0oMDAP&rs=AOn4CLA_0Rhm3bUv_7ced8oSnuMsGx-Tyg",
+ "width": 336,
+ "height": 188
+ }
+ }
+ },
+ {
+ "player": "youtube",
+ "id": "2cx3ZyJTHmM",
+ "title": "Charla sobre GIT por Jesus Amieiro en #PHPVigo Meetup #2",
+ "pubDate": null,
+ "thumbnails": {
+ "default": {
+ "url": "https://i.ytimg.com/vi/2cx3ZyJTHmM/hqdefault.jpg?sqp=-oaymwE1CKgBEF5IVfKriqkDKAgBFQAAiEIYAXABwAEG8AEB-AH-CYAC0AWKAgwIABABGHIgUygqMA8=&rs=AOn4CLCD-Ff96hBO0a_qgeHjdbcannjUUA",
+ "width": 168,
+ "height": 94
+ },
+ "medium": {
+ "url": "https://i.ytimg.com/vi/2cx3ZyJTHmM/hqdefault.jpg?sqp=-oaymwE1CMQBEG5IVfKriqkDKAgBFQAAiEIYAXABwAEG8AEB-AH-CYAC0AWKAgwIABABGHIgUygqMA8=&rs=AOn4CLCtwvEgl3VOAmK_DUKpYtIDMHt3qA",
+ "width": 196,
+ "height": 110
+ },
+ "high": {
+ "url": "https://i.ytimg.com/vi/2cx3ZyJTHmM/hqdefault.jpg?sqp=-oaymwE2CPYBEIoBSFXyq4qpAygIARUAAIhCGAFwAcABBvABAfgB_gmAAtAFigIMCAAQARhyIFMoKjAP&rs=AOn4CLA1DqqQtZhttIcGK5e4NzR5gnmPXg",
+ "width": 246,
+ "height": 138
+ },
+ "standard": {
+ "url": "https://i.ytimg.com/vi/2cx3ZyJTHmM/hqdefault.jpg?sqp=-oaymwE2CNACELwBSFXyq4qpAygIARUAAIhCGAFwAcABBvABAfgB_gmAAtAFigIMCAAQARhyIFMoKjAP&rs=AOn4CLAlX5XFtE1w1nIa8FXfIipncqYszQ",
+ "width": 336,
+ "height": 188
+ }
+ }
+ },
+ {
+ "player": "youtube",
+ "id": "7eQ6WCsi6ik",
+ "title": "Charla presentación PHPVigo #PHPVigo Meetup#1",
+ "pubDate": null,
+ "thumbnails": {
+ "default": {
+ "url": "https://i.ytimg.com/vi/7eQ6WCsi6ik/hqdefault.jpg?sqp=-oaymwEbCKgBEF5IVfKriqkDDggBFQAAiEIYAXABwAEG&rs=AOn4CLBvMnRuHWuUYscKi_8K45XJoQHMQg",
+ "width": 168,
+ "height": 94
+ },
+ "medium": {
+ "url": "https://i.ytimg.com/vi/7eQ6WCsi6ik/hqdefault.jpg?sqp=-oaymwEbCMQBEG5IVfKriqkDDggBFQAAiEIYAXABwAEG&rs=AOn4CLC31D-cZPiPHJyquZBD0p7BHqYGcw",
+ "width": 196,
+ "height": 110
+ },
+ "high": {
+ "url": "https://i.ytimg.com/vi/7eQ6WCsi6ik/hqdefault.jpg?sqp=-oaymwEcCPYBEIoBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==&rs=AOn4CLBFXWrXg-yN_667ja8h-6XoQvpmsA",
+ "width": 246,
+ "height": 138
+ },
+ "standard": {
+ "url": "https://i.ytimg.com/vi/7eQ6WCsi6ik/hqdefault.jpg?sqp=-oaymwEcCNACELwBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==&rs=AOn4CLC5HpaFD5PmWYegUZRb39Bq8Q4AiA",
+ "width": 336,
+ "height": 188
+ }
+ }
+ },
+ {
+ "player": "youtube",
+ "id": "QKRdzyq6oAI",
+ "title": "Charla sobre Ansible por Orestes Carracedo - #PHPVigo Meetup#1",
+ "pubDate": null,
+ "thumbnails": {
+ "default": {
+ "url": "https://i.ytimg.com/vi/QKRdzyq6oAI/hqdefault.jpg?sqp=-oaymwEbCKgBEF5IVfKriqkDDggBFQAAiEIYAXABwAEG&rs=AOn4CLDnjKf1q_wXSh45bJ60OZe5UqAiRw",
+ "width": 168,
+ "height": 94
+ },
+ "medium": {
+ "url": "https://i.ytimg.com/vi/QKRdzyq6oAI/hqdefault.jpg?sqp=-oaymwEbCMQBEG5IVfKriqkDDggBFQAAiEIYAXABwAEG&rs=AOn4CLDWahlzfdJ-1F20jsct72BrgLO_IA",
+ "width": 196,
+ "height": 110
+ },
+ "high": {
+ "url": "https://i.ytimg.com/vi/QKRdzyq6oAI/hqdefault.jpg?sqp=-oaymwEcCPYBEIoBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==&rs=AOn4CLBIugeMrZvLUBAbg3PRwxL9UkAb_w",
+ "width": 246,
+ "height": 138
+ },
+ "standard": {
+ "url": "https://i.ytimg.com/vi/QKRdzyq6oAI/hqdefault.jpg?sqp=-oaymwEcCNACELwBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==&rs=AOn4CLCGt7gVnmq1tXYK-jXpAV-DuYK8Nw",
+ "width": 336,
+ "height": 188
+ }
+ }
+ }
+ ],
+ "eventList": []
+ },
+ "pythonvigo": {
+ "name": "PythonVigo",
+ "logo": "https://vigotech.org/images/python_vigo.png",
+ "links": {
+ "web": "https://www.python-vigo.es/",
+ "twitter": "https://twitter.com/python_vigo",
+ "maillist": "https://lists.es.python.org/listinfo/vigo",
+ "youtube": "https://www.youtube.com/channel/UCTUXabChakosnupWEnz4xTA"
+ },
+ "events": {
+ "type": "json",
+ "source": "https://www.python-vigo.es/events.json"
+ },
+ "videos": [
+ {
+ "type": "youtube",
+ "channel_id": "UCTUXabChakosnupWEnz4xTA"
+ }
+ ],
+ "nextEvent": {
+ "date": 1671130800000,
+ "location": "Cafe UF",
+ "title": "Reunión Diciembre 2022",
+ "url": "https://www.python-vigo.es/posts/reunion-diciembre-2022/"
+ },
+ "videoList": [
+ {
+ "player": "youtube",
+ "id": "7U7vEO8AHlk",
+ "title": "Cómo evitar alucinaciones en ChatGPT con la arquitectura RAG por Maryna Bogdan",
+ "pubDate": 1740598943000,
+ "thumbnails": {
+ "default": {
+ "url": "https://i.ytimg.com/vi/7U7vEO8AHlk/default.jpg",
+ "width": 120,
+ "height": 90
+ },
+ "medium": {
+ "url": "https://i.ytimg.com/vi/7U7vEO8AHlk/mqdefault.jpg",
+ "width": 320,
+ "height": 180
+ },
+ "high": {
+ "url": "https://i.ytimg.com/vi/7U7vEO8AHlk/hqdefault.jpg",
+ "width": 480,
+ "height": 360
+ }
+ }
+ },
+ {
+ "player": "youtube",
+ "id": "PhkMZaAX3HA",
+ "title": "Tinkering with CLI: Refining your terminal toolbox with pipx por Daniel Sanchez",
+ "pubDate": 1740586740000,
+ "thumbnails": {
+ "default": {
+ "url": "https://i.ytimg.com/vi/PhkMZaAX3HA/default.jpg",
+ "width": 120,
+ "height": 90
+ },
+ "medium": {
+ "url": "https://i.ytimg.com/vi/PhkMZaAX3HA/mqdefault.jpg",
+ "width": 320,
+ "height": 180
+ },
+ "high": {
+ "url": "https://i.ytimg.com/vi/PhkMZaAX3HA/hqdefault.jpg",
+ "width": 480,
+ "height": 360
+ }
+ }
+ },
+ {
+ "player": "youtube",
+ "id": "hqXBVk4vI9M",
+ "title": "Python bajo el agua. Aplicaciones python para vehículos submarinos por Ignacio González Liaño",
+ "pubDate": 1740078265000,
+ "thumbnails": {
+ "default": {
+ "url": "https://i.ytimg.com/vi/hqXBVk4vI9M/default.jpg",
+ "width": 120,
+ "height": 90
+ },
+ "medium": {
+ "url": "https://i.ytimg.com/vi/hqXBVk4vI9M/mqdefault.jpg",
+ "width": 320,
+ "height": 180
+ },
+ "high": {
+ "url": "https://i.ytimg.com/vi/hqXBVk4vI9M/hqdefault.jpg",
+ "width": 480,
+ "height": 360
+ }
+ }
+ },
+ {
+ "player": "youtube",
+ "id": "miCqgdqrZXM",
+ "title": "Acto de apertura PyConEs",
+ "pubDate": 1727420401000,
+ "thumbnails": {
+ "default": {
+ "url": "https://i.ytimg.com/vi/miCqgdqrZXM/default.jpg",
+ "width": 120,
+ "height": 90
+ },
+ "medium": {
+ "url": "https://i.ytimg.com/vi/miCqgdqrZXM/mqdefault.jpg",
+ "width": 320,
+ "height": 180
+ },
+ "high": {
+ "url": "https://i.ytimg.com/vi/miCqgdqrZXM/hqdefault.jpg",
+ "width": 480,
+ "height": 360
+ }
+ }
+ },
+ {
+ "player": "youtube",
+ "id": "49KlM6h8sg8",
+ "title": "Acto de apertura PyConEs",
+ "pubDate": 1727372003000,
+ "thumbnails": {
+ "default": {
+ "url": "https://i.ytimg.com/vi/49KlM6h8sg8/default.jpg",
+ "width": 120,
+ "height": 90
+ },
+ "medium": {
+ "url": "https://i.ytimg.com/vi/49KlM6h8sg8/mqdefault.jpg",
+ "width": 320,
+ "height": 180
+ },
+ "high": {
+ "url": "https://i.ytimg.com/vi/49KlM6h8sg8/hqdefault.jpg",
+ "width": 480,
+ "height": 360
+ }
+ }
+ },
+ {
+ "player": "youtube",
+ "id": "2qQraO0ZIoc",
+ "title": "Acto de apertura PyConEs",
+ "pubDate": 1727370343000,
+ "thumbnails": {
+ "default": {
+ "url": "https://i.ytimg.com/vi/2qQraO0ZIoc/default.jpg",
+ "width": 120,
+ "height": 90
+ },
+ "medium": {
+ "url": "https://i.ytimg.com/vi/2qQraO0ZIoc/mqdefault.jpg",
+ "width": 320,
+ "height": 180
+ },
+ "high": {
+ "url": "https://i.ytimg.com/vi/2qQraO0ZIoc/hqdefault.jpg",
+ "width": 480,
+ "height": 360
+ }
+ }
+ },
+ {
+ "player": "youtube",
+ "id": "V-cTyi8oOLI",
+ "title": "Emisión en directo de Python Vigo",
+ "pubDate": 1705320138000,
+ "thumbnails": {
+ "default": {
+ "url": "https://i.ytimg.com/vi/V-cTyi8oOLI/default.jpg",
+ "width": 120,
+ "height": 90
+ },
+ "medium": {
+ "url": "https://i.ytimg.com/vi/V-cTyi8oOLI/mqdefault.jpg",
+ "width": 320,
+ "height": 180
+ },
+ "high": {
+ "url": "https://i.ytimg.com/vi/V-cTyi8oOLI/hqdefault.jpg",
+ "width": 480,
+ "height": 360
+ }
+ }
+ },
+ {
+ "player": "youtube",
+ "id": "M8s3styUMFs",
+ "title": "Acto de apertura PyConEs",
+ "pubDate": 1705320052000,
+ "thumbnails": {
+ "default": {
+ "url": "https://i.ytimg.com/vi/M8s3styUMFs/default.jpg",
+ "width": 120,
+ "height": 90
+ },
+ "medium": {
+ "url": "https://i.ytimg.com/vi/M8s3styUMFs/mqdefault.jpg",
+ "width": 320,
+ "height": 180
+ },
+ "high": {
+ "url": "https://i.ytimg.com/vi/M8s3styUMFs/hqdefault.jpg",
+ "width": 480,
+ "height": 360
+ }
+ }
+ },
+ {
+ "player": "youtube",
+ "id": "9P7qyb7leBA",
+ "title": "Fixtures and factories by Hector Cantó",
+ "pubDate": 1703361330000,
+ "thumbnails": {
+ "default": {
+ "url": "https://i.ytimg.com/vi/9P7qyb7leBA/default.jpg",
+ "width": 120,
+ "height": 90
+ },
+ "medium": {
+ "url": "https://i.ytimg.com/vi/9P7qyb7leBA/mqdefault.jpg",
+ "width": 320,
+ "height": 180
+ },
+ "high": {
+ "url": "https://i.ytimg.com/vi/9P7qyb7leBA/hqdefault.jpg",
+ "width": 480,
+ "height": 360
+ }
+ }
+ },
+ {
+ "player": "youtube",
+ "id": "-_Yqzx2M7AY",
+ "title": "Creando tu propio simulador cuántico en 200 líneas por Ismael Faro",
+ "pubDate": 1594968873000,
+ "thumbnails": {
+ "default": {
+ "url": "https://i.ytimg.com/vi/-_Yqzx2M7AY/default.jpg",
+ "width": 120,
+ "height": 90
+ },
+ "medium": {
+ "url": "https://i.ytimg.com/vi/-_Yqzx2M7AY/mqdefault.jpg",
+ "width": 320,
+ "height": 180
+ },
+ "high": {
+ "url": "https://i.ytimg.com/vi/-_Yqzx2M7AY/hqdefault.jpg",
+ "width": 480,
+ "height": 360
+ }
+ }
+ },
+ {
+ "player": "youtube",
+ "id": "fTZAWsABXc0",
+ "title": "Creando tu propio simulador cuántico en 200 líneas por Ismael Faro",
+ "pubDate": 1594925459000,
+ "thumbnails": {
+ "default": {
+ "url": "https://i.ytimg.com/vi/fTZAWsABXc0/default.jpg",
+ "width": 120,
+ "height": 90
+ },
+ "medium": {
+ "url": "https://i.ytimg.com/vi/fTZAWsABXc0/mqdefault.jpg",
+ "width": 320,
+ "height": 180
+ },
+ "high": {
+ "url": "https://i.ytimg.com/vi/fTZAWsABXc0/hqdefault.jpg",
+ "width": 480,
+ "height": 360
+ }
+ }
+ },
+ {
+ "player": "youtube",
+ "id": "sy233UrMikM",
+ "title": "Luis Rovirosa - Learned lessons in a real world project",
+ "pubDate": 1517562159000,
+ "thumbnails": {
+ "default": {
+ "url": "https://i.ytimg.com/vi/sy233UrMikM/default.jpg",
+ "width": 120,
+ "height": 90
+ },
+ "medium": {
+ "url": "https://i.ytimg.com/vi/sy233UrMikM/mqdefault.jpg",
+ "width": 320,
+ "height": 180
+ },
+ "high": {
+ "url": "https://i.ytimg.com/vi/sy233UrMikM/hqdefault.jpg",
+ "width": 480,
+ "height": 360
+ }
+ }
+ },
+ {
+ "player": "youtube",
+ "id": "gqvhYBCeiMY",
+ "title": "Docker en producción - José Corral",
+ "pubDate": 1507036364000,
+ "thumbnails": {
+ "default": {
+ "url": "https://i.ytimg.com/vi/gqvhYBCeiMY/default.jpg",
+ "width": 120,
+ "height": 90
+ },
+ "medium": {
+ "url": "https://i.ytimg.com/vi/gqvhYBCeiMY/mqdefault.jpg",
+ "width": 320,
+ "height": 180
+ },
+ "high": {
+ "url": "https://i.ytimg.com/vi/gqvhYBCeiMY/hqdefault.jpg",
+ "width": 480,
+ "height": 360
+ }
+ }
+ },
+ {
+ "player": "youtube",
+ "id": "cfQ-1H7bXjk",
+ "title": "Mira mamá, sin ifs - Miguel González",
+ "pubDate": 1507036217000,
+ "thumbnails": {
+ "default": {
+ "url": "https://i.ytimg.com/vi/cfQ-1H7bXjk/default.jpg",
+ "width": 120,
+ "height": 90
+ },
+ "medium": {
+ "url": "https://i.ytimg.com/vi/cfQ-1H7bXjk/mqdefault.jpg",
+ "width": 320,
+ "height": 180
+ },
+ "high": {
+ "url": "https://i.ytimg.com/vi/cfQ-1H7bXjk/hqdefault.jpg",
+ "width": 480,
+ "height": 360
+ }
+ }
+ },
+ {
+ "player": "youtube",
+ "id": "1D7VQKRgDT4",
+ "title": "Type Hinting básico, por Xurxo Fresco",
+ "pubDate": 1507017987000,
+ "thumbnails": {
+ "default": {
+ "url": "https://i.ytimg.com/vi/1D7VQKRgDT4/default.jpg",
+ "width": 120,
+ "height": 90
+ },
+ "medium": {
+ "url": "https://i.ytimg.com/vi/1D7VQKRgDT4/mqdefault.jpg",
+ "width": 320,
+ "height": 180
+ },
+ "high": {
+ "url": "https://i.ytimg.com/vi/1D7VQKRgDT4/hqdefault.jpg",
+ "width": 480,
+ "height": 360
+ }
+ }
+ },
+ {
+ "player": "youtube",
+ "id": "T1wih6Hs-Yw",
+ "title": "Brujería con Numpy.einsum, por David de la Iglesia",
+ "pubDate": null,
+ "thumbnails": {
+ "default": {
+ "url": "https://i.ytimg.com/vi/T1wih6Hs-Yw/hqdefault.jpg?sqp=-oaymwEbCKgBEF5IVfKriqkDDggBFQAAiEIYAXABwAEG&rs=AOn4CLBXzlVpf9GmywHuUQxv4O2hJFwTjg",
+ "width": 168,
+ "height": 94
+ },
+ "medium": {
+ "url": "https://i.ytimg.com/vi/T1wih6Hs-Yw/hqdefault.jpg?sqp=-oaymwEbCMQBEG5IVfKriqkDDggBFQAAiEIYAXABwAEG&rs=AOn4CLDoAm81kwtez48iHBekQOT2a8O9RA",
+ "width": 196,
+ "height": 110
+ },
+ "high": {
+ "url": "https://i.ytimg.com/vi/T1wih6Hs-Yw/hqdefault.jpg?sqp=-oaymwEcCPYBEIoBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==&rs=AOn4CLDWy924bJo0JPJiXjf2S_Df9a6mOA",
+ "width": 246,
+ "height": 138
+ },
+ "standard": {
+ "url": "https://i.ytimg.com/vi/T1wih6Hs-Yw/hqdefault.jpg?sqp=-oaymwEcCNACELwBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==&rs=AOn4CLDOR_hvVlirsyQJzULPI4XAveyRbw",
+ "width": 336,
+ "height": 188
+ }
+ }
+ },
+ {
+ "player": "youtube",
+ "id": "l8ORg4kzBoI",
+ "title": "Resolviendo la kata Args con TDD, por Javier Sánchez",
+ "pubDate": null,
+ "thumbnails": {
+ "default": {
+ "url": "https://i.ytimg.com/vi/l8ORg4kzBoI/hqdefault.jpg?sqp=-oaymwEbCKgBEF5IVfKriqkDDggBFQAAiEIYAXABwAEG&rs=AOn4CLANB6IpTf94OAPanF9Lyxwr4IXWug",
+ "width": 168,
+ "height": 94
+ },
+ "medium": {
+ "url": "https://i.ytimg.com/vi/l8ORg4kzBoI/hqdefault.jpg?sqp=-oaymwEbCMQBEG5IVfKriqkDDggBFQAAiEIYAXABwAEG&rs=AOn4CLBZOmT_-MSbJESXbgY6QpgkKdPsgQ",
+ "width": 196,
+ "height": 110
+ },
+ "high": {
+ "url": "https://i.ytimg.com/vi/l8ORg4kzBoI/hqdefault.jpg?sqp=-oaymwEcCPYBEIoBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==&rs=AOn4CLCrMjwFrqEb8KBFmbDmAPCCChn39w",
+ "width": 246,
+ "height": 138
+ },
+ "standard": {
+ "url": "https://i.ytimg.com/vi/l8ORg4kzBoI/hqdefault.jpg?sqp=-oaymwEcCNACELwBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==&rs=AOn4CLD7mHoa5HQQnd9ui-U3RRPPw-iPtQ",
+ "width": 336,
+ "height": 188
+ }
+ }
+ },
+ {
+ "player": "youtube",
+ "id": "09hfTif_FaE",
+ "title": "Algoritmo Binary Search, por Antón Yuste",
+ "pubDate": null,
+ "thumbnails": {
+ "default": {
+ "url": "https://i.ytimg.com/vi/09hfTif_FaE/hqdefault.jpg?sqp=-oaymwEbCKgBEF5IVfKriqkDDggBFQAAiEIYAXABwAEG&rs=AOn4CLA9uovEAcbRhsCx-gF8UrngJ5myAg",
+ "width": 168,
+ "height": 94
+ },
+ "medium": {
+ "url": "https://i.ytimg.com/vi/09hfTif_FaE/hqdefault.jpg?sqp=-oaymwEbCMQBEG5IVfKriqkDDggBFQAAiEIYAXABwAEG&rs=AOn4CLCG0ld9vaeIAghajG68vUQPDuwz-w",
+ "width": 196,
+ "height": 110
+ },
+ "high": {
+ "url": "https://i.ytimg.com/vi/09hfTif_FaE/hqdefault.jpg?sqp=-oaymwEcCPYBEIoBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==&rs=AOn4CLD9dQn7y9ZGZRgKcwqDYuyViDMAAQ",
+ "width": 246,
+ "height": 138
+ },
+ "standard": {
+ "url": "https://i.ytimg.com/vi/09hfTif_FaE/hqdefault.jpg?sqp=-oaymwEcCNACELwBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==&rs=AOn4CLAtc4l81hkA1kWFDPAJ2RNMq-skow",
+ "width": 336,
+ "height": 188
+ }
+ }
+ },
+ {
+ "player": "youtube",
+ "id": "RODHAlBFANo",
+ "title": "Great balls of fire (Visualizando datos con Dash), por Iván Nieto",
+ "pubDate": null,
+ "thumbnails": {
+ "default": {
+ "url": "https://i.ytimg.com/vi/RODHAlBFANo/hqdefault.jpg?sqp=-oaymwEbCKgBEF5IVfKriqkDDggBFQAAiEIYAXABwAEG&rs=AOn4CLD-b6RZGidekHWM-67C43S0SJVnQw",
+ "width": 168,
+ "height": 94
+ },
+ "medium": {
+ "url": "https://i.ytimg.com/vi/RODHAlBFANo/hqdefault.jpg?sqp=-oaymwEbCMQBEG5IVfKriqkDDggBFQAAiEIYAXABwAEG&rs=AOn4CLDOrUN0WpWtT3lnx58psKLtGbay_g",
+ "width": 196,
+ "height": 110
+ },
+ "high": {
+ "url": "https://i.ytimg.com/vi/RODHAlBFANo/hqdefault.jpg?sqp=-oaymwEcCPYBEIoBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==&rs=AOn4CLDQ5u-_3stk-ua5V3zZZTEIXKHNeQ",
+ "width": 246,
+ "height": 138
+ },
+ "standard": {
+ "url": "https://i.ytimg.com/vi/RODHAlBFANo/hqdefault.jpg?sqp=-oaymwEcCNACELwBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==&rs=AOn4CLDrEiM_29V220bW-s0kb527BPR-Vg",
+ "width": 336,
+ "height": 188
+ }
+ }
+ },
+ {
+ "player": "youtube",
+ "id": "Y-W9t8KWNz4",
+ "title": "This summer master the mosquittos, por Alex Hermida",
+ "pubDate": null,
+ "thumbnails": {
+ "default": {
+ "url": "https://i.ytimg.com/vi/Y-W9t8KWNz4/hqdefault.jpg?sqp=-oaymwEbCKgBEF5IVfKriqkDDggBFQAAiEIYAXABwAEG&rs=AOn4CLAqUVC-kwS0oUITcvBYe7DKtXUI9g",
+ "width": 168,
+ "height": 94
+ },
+ "medium": {
+ "url": "https://i.ytimg.com/vi/Y-W9t8KWNz4/hqdefault.jpg?sqp=-oaymwEbCMQBEG5IVfKriqkDDggBFQAAiEIYAXABwAEG&rs=AOn4CLA_iU8sUW6SJvqEY2Auv0cXJHx0Bg",
+ "width": 196,
+ "height": 110
+ },
+ "high": {
+ "url": "https://i.ytimg.com/vi/Y-W9t8KWNz4/hqdefault.jpg?sqp=-oaymwEcCPYBEIoBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==&rs=AOn4CLAZr0C58D5p3OIZZkNM_aVO390yPA",
+ "width": 246,
+ "height": 138
+ },
+ "standard": {
+ "url": "https://i.ytimg.com/vi/Y-W9t8KWNz4/hqdefault.jpg?sqp=-oaymwEcCNACELwBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==&rs=AOn4CLBFsJEgD2WDyKes3FoXSRhDJo5KdQ",
+ "width": 336,
+ "height": 188
+ }
+ }
+ },
+ {
+ "player": "youtube",
+ "id": "WrL5H0Tmq-w",
+ "title": "APIS de Machine Learning: como usarlas desde Python. Por David de la Iglesia.",
+ "pubDate": null,
+ "thumbnails": {
+ "default": {
+ "url": "https://i.ytimg.com/vi/WrL5H0Tmq-w/hqdefault.jpg?sqp=-oaymwEbCKgBEF5IVfKriqkDDggBFQAAiEIYAXABwAEG&rs=AOn4CLDYvTs-g-kQwzAIRpWlecGCjQDJ-w",
+ "width": 168,
+ "height": 94
+ },
+ "medium": {
+ "url": "https://i.ytimg.com/vi/WrL5H0Tmq-w/hqdefault.jpg?sqp=-oaymwEbCMQBEG5IVfKriqkDDggBFQAAiEIYAXABwAEG&rs=AOn4CLAfOtC7dYQwnytQWjwOIUcnaxHQtg",
+ "width": 196,
+ "height": 110
+ },
+ "high": {
+ "url": "https://i.ytimg.com/vi/WrL5H0Tmq-w/hqdefault.jpg?sqp=-oaymwEcCPYBEIoBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==&rs=AOn4CLAdWNvTMdCc0WGOSXal-IteJvaj0w",
+ "width": 246,
+ "height": 138
+ },
+ "standard": {
+ "url": "https://i.ytimg.com/vi/WrL5H0Tmq-w/hqdefault.jpg?sqp=-oaymwEcCNACELwBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==&rs=AOn4CLCJ5MMw-7UgYp4dnRy47EOwbjj8uQ",
+ "width": 336,
+ "height": 188
+ }
+ }
+ },
+ {
+ "player": "youtube",
+ "id": "Q9c0dQTEyc8",
+ "title": "Codenamize: presentación de la librería. Por José Juan Montes.",
+ "pubDate": null,
+ "thumbnails": {
+ "default": {
+ "url": "https://i.ytimg.com/vi/Q9c0dQTEyc8/hqdefault.jpg?sqp=-oaymwEbCKgBEF5IVfKriqkDDggBFQAAiEIYAXABwAEG&rs=AOn4CLAHQ7nY7FHe7d70trReWE9PA2vBig",
+ "width": 168,
+ "height": 94
+ },
+ "medium": {
+ "url": "https://i.ytimg.com/vi/Q9c0dQTEyc8/hqdefault.jpg?sqp=-oaymwEbCMQBEG5IVfKriqkDDggBFQAAiEIYAXABwAEG&rs=AOn4CLD7NyO7OH7QeocoIMVdPtjFNWYrrQ",
+ "width": 196,
+ "height": 110
+ },
+ "high": {
+ "url": "https://i.ytimg.com/vi/Q9c0dQTEyc8/hqdefault.jpg?sqp=-oaymwEcCPYBEIoBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==&rs=AOn4CLBKSPSLSfGWpoLm4Bthc1XYvRuMJA",
+ "width": 246,
+ "height": 138
+ },
+ "standard": {
+ "url": "https://i.ytimg.com/vi/Q9c0dQTEyc8/hqdefault.jpg?sqp=-oaymwEcCNACELwBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==&rs=AOn4CLDA6OfQpU2glbXbXnLFOos03UDA2Q",
+ "width": 336,
+ "height": 188
+ }
+ }
+ },
+ {
+ "player": "youtube",
+ "id": "hjx-lqLlrhw",
+ "title": "PythonVigo - David de la Iglesia",
+ "pubDate": null,
+ "thumbnails": {
+ "default": {
+ "url": "https://i.ytimg.com/vi/hjx-lqLlrhw/hqdefault.jpg?sqp=-oaymwEbCKgBEF5IVfKriqkDDggBFQAAiEIYAXABwAEG&rs=AOn4CLBYL7SwJCBpvC_0aBjGQhyc_cX8Lw",
+ "width": 168,
+ "height": 94
+ },
+ "medium": {
+ "url": "https://i.ytimg.com/vi/hjx-lqLlrhw/hqdefault.jpg?sqp=-oaymwEbCMQBEG5IVfKriqkDDggBFQAAiEIYAXABwAEG&rs=AOn4CLDHmy9TMqSPxX0di2O3s2KzVK0zDA",
+ "width": 196,
+ "height": 110
+ },
+ "high": {
+ "url": "https://i.ytimg.com/vi/hjx-lqLlrhw/hqdefault.jpg?sqp=-oaymwEcCPYBEIoBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==&rs=AOn4CLCMBuUH7OJxxzhtDEq7VRARWlu26w",
+ "width": 246,
+ "height": 138
+ },
+ "standard": {
+ "url": "https://i.ytimg.com/vi/hjx-lqLlrhw/hqdefault.jpg?sqp=-oaymwEcCNACELwBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==&rs=AOn4CLAjtLKb34cFte7DIwqbViR3Kqh9vA",
+ "width": 336,
+ "height": 188
+ }
+ }
+ },
+ {
+ "player": "youtube",
+ "id": "FwgpPsiYg_o",
+ "title": "PythonVigo - jython - Antón R. Yuste",
+ "pubDate": null,
+ "thumbnails": {
+ "default": {
+ "url": "https://i.ytimg.com/vi/FwgpPsiYg_o/hqdefault.jpg?sqp=-oaymwEbCKgBEF5IVfKriqkDDggBFQAAiEIYAXABwAEG&rs=AOn4CLAoIHOJwV9rl2oYkd5Vxw8j-U7lBA",
+ "width": 168,
+ "height": 94
+ },
+ "medium": {
+ "url": "https://i.ytimg.com/vi/FwgpPsiYg_o/hqdefault.jpg?sqp=-oaymwEbCMQBEG5IVfKriqkDDggBFQAAiEIYAXABwAEG&rs=AOn4CLCYYR95NjeyaMHyQfwKMHCVz8NDOw",
+ "width": 196,
+ "height": 110
+ },
+ "high": {
+ "url": "https://i.ytimg.com/vi/FwgpPsiYg_o/hqdefault.jpg?sqp=-oaymwEcCPYBEIoBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==&rs=AOn4CLDbFbpU6Qb1G58MQqS2-YQgb-cHvg",
+ "width": 246,
+ "height": 138
+ },
+ "standard": {
+ "url": "https://i.ytimg.com/vi/FwgpPsiYg_o/hqdefault.jpg?sqp=-oaymwEcCNACELwBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==&rs=AOn4CLC_l6jUKGydJ7D_J0NIhOfpkdoTew",
+ "width": 336,
+ "height": 188
+ }
+ }
+ },
+ {
+ "player": "youtube",
+ "id": "lmS4x_1Cz-c",
+ "title": "PythonVigo - logging - Miguel Gonzalez",
+ "pubDate": null,
+ "thumbnails": {
+ "default": {
+ "url": "https://i.ytimg.com/vi/lmS4x_1Cz-c/hqdefault.jpg?sqp=-oaymwEbCKgBEF5IVfKriqkDDggBFQAAiEIYAXABwAEG&rs=AOn4CLD5UIy97doXGL311RhLTA4vvVfvMQ",
+ "width": 168,
+ "height": 94
+ },
+ "medium": {
+ "url": "https://i.ytimg.com/vi/lmS4x_1Cz-c/hqdefault.jpg?sqp=-oaymwEbCMQBEG5IVfKriqkDDggBFQAAiEIYAXABwAEG&rs=AOn4CLBzYgHg_rqcio-GWZVprBdLeSPvEw",
+ "width": 196,
+ "height": 110
+ },
+ "high": {
+ "url": "https://i.ytimg.com/vi/lmS4x_1Cz-c/hqdefault.jpg?sqp=-oaymwEcCPYBEIoBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==&rs=AOn4CLDMnR_JbJsvmyQPrRyWmGJpt0fFMQ",
+ "width": 246,
+ "height": 138
+ },
+ "standard": {
+ "url": "https://i.ytimg.com/vi/lmS4x_1Cz-c/hqdefault.jpg?sqp=-oaymwEcCNACELwBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==&rs=AOn4CLBSt2aW1O2wsVXjO222gTxP88CdRg",
+ "width": 336,
+ "height": 188
+ }
+ }
+ },
+ {
+ "player": "youtube",
+ "id": "ef4LLtomZKw",
+ "title": "PythonVigo - oklog - José COrral",
+ "pubDate": null,
+ "thumbnails": {
+ "default": {
+ "url": "https://i.ytimg.com/vi/ef4LLtomZKw/hqdefault.jpg?sqp=-oaymwEbCKgBEF5IVfKriqkDDggBFQAAiEIYAXABwAEG&rs=AOn4CLD_H-d7Ashu1DdA7o6-SAeTXOfRmA",
+ "width": 168,
+ "height": 94
+ },
+ "medium": {
+ "url": "https://i.ytimg.com/vi/ef4LLtomZKw/hqdefault.jpg?sqp=-oaymwEbCMQBEG5IVfKriqkDDggBFQAAiEIYAXABwAEG&rs=AOn4CLBraAmM6_DY6pt2vP9hn2PGn5U_qA",
+ "width": 196,
+ "height": 110
+ },
+ "high": {
+ "url": "https://i.ytimg.com/vi/ef4LLtomZKw/hqdefault.jpg?sqp=-oaymwEcCPYBEIoBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==&rs=AOn4CLCaXqhXDrODBL5puVKA3Tj9F1Fpug",
+ "width": 246,
+ "height": 138
+ },
+ "standard": {
+ "url": "https://i.ytimg.com/vi/ef4LLtomZKw/hqdefault.jpg?sqp=-oaymwEcCNACELwBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==&rs=AOn4CLDQpQmcoYgVML2bqJ4VnCyRGVQwBw",
+ "width": 336,
+ "height": 188
+ }
+ }
+ },
+ {
+ "player": "youtube",
+ "id": "Z_AzC6HkZk8",
+ "title": "Emisión en directo Python Vigo",
+ "pubDate": null,
+ "thumbnails": {
+ "default": {
+ "url": "https://i.ytimg.com/vi/Z_AzC6HkZk8/hqdefault.jpg?sqp=-oaymwEbCKgBEF5IVfKriqkDDggBFQAAiEIYAXABwAEG&rs=AOn4CLDWD_vXWwcOgXCaptOj6HVCA67gtA",
+ "width": 168,
+ "height": 94
+ },
+ "medium": {
+ "url": "https://i.ytimg.com/vi/Z_AzC6HkZk8/hqdefault.jpg?sqp=-oaymwEbCMQBEG5IVfKriqkDDggBFQAAiEIYAXABwAEG&rs=AOn4CLCeR9OEJvbefBly099SbJt6jByFKw",
+ "width": 196,
+ "height": 110
+ },
+ "high": {
+ "url": "https://i.ytimg.com/vi/Z_AzC6HkZk8/hqdefault.jpg?sqp=-oaymwEcCPYBEIoBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==&rs=AOn4CLDlRZOq0uZXCP0PWSqec2bqLCmPvQ",
+ "width": 246,
+ "height": 138
+ },
+ "standard": {
+ "url": "https://i.ytimg.com/vi/Z_AzC6HkZk8/hqdefault.jpg?sqp=-oaymwEcCNACELwBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==&rs=AOn4CLAKAw9OJzMaQ982P5PFatKiK1Mxkg",
+ "width": 336,
+ "height": 188
+ }
+ }
+ },
+ {
+ "player": "youtube",
+ "id": "9DPtfApk8co",
+ "title": "Emisión en directo Python Vigo",
+ "pubDate": null,
+ "thumbnails": {
+ "default": {
+ "url": "https://i.ytimg.com/vi/9DPtfApk8co/hqdefault.jpg?sqp=-oaymwEbCKgBEF5IVfKriqkDDggBFQAAiEIYAXABwAEG&rs=AOn4CLBYKVQYHrEexqCOSVnWjdgVXc4d8g",
+ "width": 168,
+ "height": 94
+ },
+ "medium": {
+ "url": "https://i.ytimg.com/vi/9DPtfApk8co/hqdefault.jpg?sqp=-oaymwEbCMQBEG5IVfKriqkDDggBFQAAiEIYAXABwAEG&rs=AOn4CLD-9w6UERB7bmQpahsRPPU67lo8kg",
+ "width": 196,
+ "height": 110
+ },
+ "high": {
+ "url": "https://i.ytimg.com/vi/9DPtfApk8co/hqdefault.jpg?sqp=-oaymwEcCPYBEIoBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==&rs=AOn4CLB4nrYOr9qHInYa4ThQ3UvQFbn0mQ",
+ "width": 246,
+ "height": 138
+ },
+ "standard": {
+ "url": "https://i.ytimg.com/vi/9DPtfApk8co/hqdefault.jpg?sqp=-oaymwEcCNACELwBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==&rs=AOn4CLDgmyKHjMuveU_qMDDha1S5pDwHpg",
+ "width": 336,
+ "height": 188
+ }
+ }
+ },
+ {
+ "player": "youtube",
+ "id": "Q7C9-_yq6wk",
+ "title": "Emisión en directo Python Vigo",
+ "pubDate": null,
+ "thumbnails": {
+ "default": {
+ "url": "https://i.ytimg.com/vi/Q7C9-_yq6wk/hqdefault.jpg?sqp=-oaymwEbCKgBEF5IVfKriqkDDggBFQAAiEIYAXABwAEG&rs=AOn4CLD2O-_ARk-ijdmhQLjhW6EdQ_kZzQ",
+ "width": 168,
+ "height": 94
+ },
+ "medium": {
+ "url": "https://i.ytimg.com/vi/Q7C9-_yq6wk/hqdefault.jpg?sqp=-oaymwEbCMQBEG5IVfKriqkDDggBFQAAiEIYAXABwAEG&rs=AOn4CLCc_kYh7f-xKarAm6Espjh_WYJ-tw",
+ "width": 196,
+ "height": 110
+ },
+ "high": {
+ "url": "https://i.ytimg.com/vi/Q7C9-_yq6wk/hqdefault.jpg?sqp=-oaymwEcCPYBEIoBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==&rs=AOn4CLBMLQ8AyI-ouVhvGHWgc5AzONSbdw",
+ "width": 246,
+ "height": 138
+ },
+ "standard": {
+ "url": "https://i.ytimg.com/vi/Q7C9-_yq6wk/hqdefault.jpg?sqp=-oaymwEcCNACELwBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==&rs=AOn4CLAa61AJjjj7Oa4RWFppffcE_YnS9g",
+ "width": 336,
+ "height": 188
+ }
+ }
+ },
+ {
+ "player": "youtube",
+ "id": "NPsTUtU8QXc",
+ "title": "Emisión en directo Python Vigo",
+ "pubDate": null,
+ "thumbnails": {
+ "default": {
+ "url": "https://i.ytimg.com/vi/NPsTUtU8QXc/hqdefault.jpg?sqp=-oaymwEbCKgBEF5IVfKriqkDDggBFQAAiEIYAXABwAEG&rs=AOn4CLAwkJIeGLvc6VTPvT3eRhrU0LCQ9w",
+ "width": 168,
+ "height": 94
+ },
+ "medium": {
+ "url": "https://i.ytimg.com/vi/NPsTUtU8QXc/hqdefault.jpg?sqp=-oaymwEbCMQBEG5IVfKriqkDDggBFQAAiEIYAXABwAEG&rs=AOn4CLAn2foiEvLQhizL8dmaV59lXU4ifA",
+ "width": 196,
+ "height": 110
+ },
+ "high": {
+ "url": "https://i.ytimg.com/vi/NPsTUtU8QXc/hqdefault.jpg?sqp=-oaymwEcCPYBEIoBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==&rs=AOn4CLC8hL77C8CNTp3yK9-V3oxISxNygw",
+ "width": 246,
+ "height": 138
+ },
+ "standard": {
+ "url": "https://i.ytimg.com/vi/NPsTUtU8QXc/hqdefault.jpg?sqp=-oaymwEcCNACELwBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==&rs=AOn4CLCbFI-m2bKGPIJ0iYTbLTewfo8OcA",
+ "width": 336,
+ "height": 188
+ }
+ }
+ },
+ {
+ "player": "youtube",
+ "id": "pw97r0EO7So",
+ "title": "Emisión en directo Python Vigo",
+ "pubDate": null,
+ "thumbnails": {
+ "default": {
+ "url": "https://i.ytimg.com/vi/pw97r0EO7So/hqdefault.jpg?sqp=-oaymwEbCKgBEF5IVfKriqkDDggBFQAAiEIYAXABwAEG&rs=AOn4CLDyDlpNa4Y-mpOJbcFS_r0VoVVdDw",
+ "width": 168,
+ "height": 94
+ },
+ "medium": {
+ "url": "https://i.ytimg.com/vi/pw97r0EO7So/hqdefault.jpg?sqp=-oaymwEbCMQBEG5IVfKriqkDDggBFQAAiEIYAXABwAEG&rs=AOn4CLCbvKOcg3FIIwcrp2uXxAEv8KkYMQ",
+ "width": 196,
+ "height": 110
+ },
+ "high": {
+ "url": "https://i.ytimg.com/vi/pw97r0EO7So/hqdefault.jpg?sqp=-oaymwEcCPYBEIoBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==&rs=AOn4CLDbgmvFcqT7GTjGOMR9QtC6leTmnw",
+ "width": 246,
+ "height": 138
+ },
+ "standard": {
+ "url": "https://i.ytimg.com/vi/pw97r0EO7So/hqdefault.jpg?sqp=-oaymwEcCNACELwBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==&rs=AOn4CLAfcweT49X8Elu7U490AlwTiSeOmw",
+ "width": 336,
+ "height": 188
+ }
+ }
+ },
+ {
+ "player": "youtube",
+ "id": "QWF0qd26gWM",
+ "title": "Agile, Scrum y Kanban - Pepe Doval - PyDay Galicia",
+ "pubDate": null,
+ "thumbnails": {
+ "default": {
+ "url": "https://i.ytimg.com/vi/QWF0qd26gWM/hqdefault.jpg?sqp=-oaymwE1CKgBEF5IVfKriqkDKAgBFQAAiEIYAXABwAEG8AEB-AH-CIAC0AWKAgwIABABGGUgZShlMA8=&rs=AOn4CLDAuFWSmEyMasBBR0p0FZZ5A2LmOw",
+ "width": 168,
+ "height": 94
+ },
+ "medium": {
+ "url": "https://i.ytimg.com/vi/QWF0qd26gWM/hqdefault.jpg?sqp=-oaymwE1CMQBEG5IVfKriqkDKAgBFQAAiEIYAXABwAEG8AEB-AH-CIAC0AWKAgwIABABGGUgZShlMA8=&rs=AOn4CLDISUIRwZJYqiY3NcElKNsecmHKEQ",
+ "width": 196,
+ "height": 110
+ },
+ "high": {
+ "url": "https://i.ytimg.com/vi/QWF0qd26gWM/hqdefault.jpg?sqp=-oaymwE2CPYBEIoBSFXyq4qpAygIARUAAIhCGAFwAcABBvABAfgB_giAAtAFigIMCAAQARhlIGUoZTAP&rs=AOn4CLAU4VTJiT_kN2IrqWUBpQr9H82x0w",
+ "width": 246,
+ "height": 138
+ },
+ "standard": {
+ "url": "https://i.ytimg.com/vi/QWF0qd26gWM/hqdefault.jpg?sqp=-oaymwE2CNACELwBSFXyq4qpAygIARUAAIhCGAFwAcABBvABAfgB_giAAtAFigIMCAAQARhlIGUoZTAP&rs=AOn4CLDL2YCJAQN-mmPr1iSGQngAtG8BIg",
+ "width": 336,
+ "height": 188
+ }
+ }
+ },
+ {
+ "player": "youtube",
+ "id": "2X72HTZTgLU",
+ "title": "Introducción a Machine Learning con Python - Xurxo Fresco - PyDay",
+ "pubDate": null,
+ "thumbnails": {
+ "default": {
+ "url": "https://i.ytimg.com/vi/2X72HTZTgLU/hqdefault.jpg?sqp=-oaymwE1CKgBEF5IVfKriqkDKAgBFQAAiEIYAXABwAEG8AEB-AH-CIAC0AWKAgwIABABGGUgZShlMA8=&rs=AOn4CLBzCIreGcIRv7CpxuPSHXrln9cAUw",
+ "width": 168,
+ "height": 94
+ },
+ "medium": {
+ "url": "https://i.ytimg.com/vi/2X72HTZTgLU/hqdefault.jpg?sqp=-oaymwE1CMQBEG5IVfKriqkDKAgBFQAAiEIYAXABwAEG8AEB-AH-CIAC0AWKAgwIABABGGUgZShlMA8=&rs=AOn4CLBseGQc30J9mQX5Afg52E2_IWoesQ",
+ "width": 196,
+ "height": 110
+ },
+ "high": {
+ "url": "https://i.ytimg.com/vi/2X72HTZTgLU/hqdefault.jpg?sqp=-oaymwE2CPYBEIoBSFXyq4qpAygIARUAAIhCGAFwAcABBvABAfgB_giAAtAFigIMCAAQARhlIGUoZTAP&rs=AOn4CLD_Y-RuJOs0HXAC6H99UulR0Uydyw",
+ "width": 246,
+ "height": 138
+ },
+ "standard": {
+ "url": "https://i.ytimg.com/vi/2X72HTZTgLU/hqdefault.jpg?sqp=-oaymwE2CNACELwBSFXyq4qpAygIARUAAIhCGAFwAcABBvABAfgB_giAAtAFigIMCAAQARhlIGUoZTAP&rs=AOn4CLCanPqFwTs6IwWcitfCLgzO82WNuQ",
+ "width": 336,
+ "height": 188
+ }
+ }
+ },
+ {
+ "player": "youtube",
+ "id": "qWHoyvLUK-U",
+ "title": "Mi primera metaclase: un ejemplo práctico - Miguel González Álvarez - PyDay",
+ "pubDate": null,
+ "thumbnails": {
+ "default": {
+ "url": "https://i.ytimg.com/vi/qWHoyvLUK-U/hqdefault.jpg?sqp=-oaymwE1CKgBEF5IVfKriqkDKAgBFQAAiEIYAXABwAEG8AEB-AH-CIAC0AWKAgwIABABGGUgZShlMA8=&rs=AOn4CLB7AXOndd5ryyFV4GzrMYqXVVuuzg",
+ "width": 168,
+ "height": 94
+ },
+ "medium": {
+ "url": "https://i.ytimg.com/vi/qWHoyvLUK-U/hqdefault.jpg?sqp=-oaymwE1CMQBEG5IVfKriqkDKAgBFQAAiEIYAXABwAEG8AEB-AH-CIAC0AWKAgwIABABGGUgZShlMA8=&rs=AOn4CLDvKRlaOzV6XOZZ6iKaNW5Qr9t74A",
+ "width": 196,
+ "height": 110
+ },
+ "high": {
+ "url": "https://i.ytimg.com/vi/qWHoyvLUK-U/hqdefault.jpg?sqp=-oaymwE2CPYBEIoBSFXyq4qpAygIARUAAIhCGAFwAcABBvABAfgB_giAAtAFigIMCAAQARhlIGUoZTAP&rs=AOn4CLCMyH5C44YAUk_H8tKWFmxNkV54cw",
+ "width": 246,
+ "height": 138
+ },
+ "standard": {
+ "url": "https://i.ytimg.com/vi/qWHoyvLUK-U/hqdefault.jpg?sqp=-oaymwE2CNACELwBSFXyq4qpAygIARUAAIhCGAFwAcABBvABAfgB_giAAtAFigIMCAAQARhlIGUoZTAP&rs=AOn4CLA-KKa6yEQ7XnjyXHOuXw1ZSjlspQ",
+ "width": 336,
+ "height": 188
+ }
+ }
+ },
+ {
+ "player": "youtube",
+ "id": "d7y88pMfNoE",
+ "title": "¡Eureka! (Python y ciencia) - ¡Eureka! (Python y ciencia) - PyDay Galicia",
+ "pubDate": null,
+ "thumbnails": {
+ "default": {
+ "url": "https://i.ytimg.com/vi/d7y88pMfNoE/hqdefault.jpg?sqp=-oaymwE1CKgBEF5IVfKriqkDKAgBFQAAiEIYAXABwAEG8AEB-AH-CIAC0AWKAgwIABABGHIgUygsMA8=&rs=AOn4CLAlPjOvOhlqJFqp1PzPF7t9kcKHbw",
+ "width": 168,
+ "height": 94
+ },
+ "medium": {
+ "url": "https://i.ytimg.com/vi/d7y88pMfNoE/hqdefault.jpg?sqp=-oaymwE1CMQBEG5IVfKriqkDKAgBFQAAiEIYAXABwAEG8AEB-AH-CIAC0AWKAgwIABABGHIgUygsMA8=&rs=AOn4CLDmT8M4bBAIr6OjPqfWtnbu-h93Gg",
+ "width": 196,
+ "height": 110
+ },
+ "high": {
+ "url": "https://i.ytimg.com/vi/d7y88pMfNoE/hqdefault.jpg?sqp=-oaymwE2CPYBEIoBSFXyq4qpAygIARUAAIhCGAFwAcABBvABAfgB_giAAtAFigIMCAAQARhyIFMoLDAP&rs=AOn4CLBtD23x51JPwOvVPr4imiCL8jyITQ",
+ "width": 246,
+ "height": 138
+ },
+ "standard": {
+ "url": "https://i.ytimg.com/vi/d7y88pMfNoE/hqdefault.jpg?sqp=-oaymwE2CNACELwBSFXyq4qpAygIARUAAIhCGAFwAcABBvABAfgB_giAAtAFigIMCAAQARhyIFMoLDAP&rs=AOn4CLBq1FaDYAm_rsvqafEwVWN00BIw_w",
+ "width": 336,
+ "height": 188
+ }
+ }
+ },
+ {
+ "player": "youtube",
+ "id": "XN98drGum7s",
+ "title": "Calling to the future - Eloy Coto - PyDay Galicia",
+ "pubDate": null,
+ "thumbnails": {
+ "default": {
+ "url": "https://i.ytimg.com/vi/XN98drGum7s/hqdefault.jpg?sqp=-oaymwE1CKgBEF5IVfKriqkDKAgBFQAAiEIYAXABwAEG8AEB-AH-CIAC0AWKAgwIABABGDsgZSg5MA8=&rs=AOn4CLCVtvOnBcs06YolzgowkgAZACXPmQ",
+ "width": 168,
+ "height": 94
+ },
+ "medium": {
+ "url": "https://i.ytimg.com/vi/XN98drGum7s/hqdefault.jpg?sqp=-oaymwE1CMQBEG5IVfKriqkDKAgBFQAAiEIYAXABwAEG8AEB-AH-CIAC0AWKAgwIABABGDsgZSg5MA8=&rs=AOn4CLAi0brkU6h1ZVNlwC9X6YjpvpD51g",
+ "width": 196,
+ "height": 110
+ },
+ "high": {
+ "url": "https://i.ytimg.com/vi/XN98drGum7s/hqdefault.jpg?sqp=-oaymwE2CPYBEIoBSFXyq4qpAygIARUAAIhCGAFwAcABBvABAfgB_giAAtAFigIMCAAQARg7IGUoOTAP&rs=AOn4CLBwDIdPzdBe0rzbPwQEeHqiqU-NWA",
+ "width": 246,
+ "height": 138
+ },
+ "standard": {
+ "url": "https://i.ytimg.com/vi/XN98drGum7s/hqdefault.jpg?sqp=-oaymwE2CNACELwBSFXyq4qpAygIARUAAIhCGAFwAcABBvABAfgB_giAAtAFigIMCAAQARg7IGUoOTAP&rs=AOn4CLCgFUFZhRbyGDTI4256aocgQx5v4w",
+ "width": 336,
+ "height": 188
+ }
+ }
+ },
+ {
+ "player": "youtube",
+ "id": "IY_6vY-M60Y",
+ "title": "Metodos magicos python",
+ "pubDate": null,
+ "thumbnails": {
+ "default": {
+ "url": "https://i.ytimg.com/vi/IY_6vY-M60Y/hqdefault.jpg?sqp=-oaymwE1CKgBEF5IVfKriqkDKAgBFQAAiEIYAXABwAEG8AEB-AH-CYAC0AWKAgwIABABGHIgTShBMA8=&rs=AOn4CLA7Iis2alAm0CLCUvv3rsOoBEaucQ",
+ "width": 168,
+ "height": 94
+ },
+ "medium": {
+ "url": "https://i.ytimg.com/vi/IY_6vY-M60Y/hqdefault.jpg?sqp=-oaymwE1CMQBEG5IVfKriqkDKAgBFQAAiEIYAXABwAEG8AEB-AH-CYAC0AWKAgwIABABGHIgTShBMA8=&rs=AOn4CLA1_AljqMzRGBW4RmNsvddGxsBx0A",
+ "width": 196,
+ "height": 110
+ },
+ "high": {
+ "url": "https://i.ytimg.com/vi/IY_6vY-M60Y/hqdefault.jpg?sqp=-oaymwE2CPYBEIoBSFXyq4qpAygIARUAAIhCGAFwAcABBvABAfgB_gmAAtAFigIMCAAQARhyIE0oQTAP&rs=AOn4CLDFV8vPU99fLUeJA2ZcZDL7_awMEg",
+ "width": 246,
+ "height": 138
+ },
+ "standard": {
+ "url": "https://i.ytimg.com/vi/IY_6vY-M60Y/hqdefault.jpg?sqp=-oaymwE2CNACELwBSFXyq4qpAygIARUAAIhCGAFwAcABBvABAfgB_gmAAtAFigIMCAAQARhyIE0oQTAP&rs=AOn4CLBOCObX4S7Gdwwv5wSAhCSwhyKBOw",
+ "width": 336,
+ "height": 188
+ }
+ }
+ },
+ {
+ "player": "youtube",
+ "id": "QfXsn_fC0NQ",
+ "title": "#GameDev at Python Vigo",
+ "pubDate": null,
+ "thumbnails": {
+ "default": {
+ "url": "https://i.ytimg.com/vi/QfXsn_fC0NQ/hqdefault.jpg?sqp=-oaymwEbCKgBEF5IVfKriqkDDggBFQAAiEIYAXABwAEG&rs=AOn4CLBgFVLOBNjz4XRo1iuo_qLC51APRg",
+ "width": 168,
+ "height": 94
+ },
+ "medium": {
+ "url": "https://i.ytimg.com/vi/QfXsn_fC0NQ/hqdefault.jpg?sqp=-oaymwEbCMQBEG5IVfKriqkDDggBFQAAiEIYAXABwAEG&rs=AOn4CLCVQ6CgXY5wRpAOJYoUC-1pPCvx1w",
+ "width": 196,
+ "height": 110
+ },
+ "high": {
+ "url": "https://i.ytimg.com/vi/QfXsn_fC0NQ/hqdefault.jpg?sqp=-oaymwEcCPYBEIoBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==&rs=AOn4CLC4LCjGr9blxRDfRzXJz46WBx2MlQ",
+ "width": 246,
+ "height": 138
+ },
+ "standard": {
+ "url": "https://i.ytimg.com/vi/QfXsn_fC0NQ/hqdefault.jpg?sqp=-oaymwEcCNACELwBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==&rs=AOn4CLDtCpe3z0_pxaODGZ2LzUExeeAeiw",
+ "width": 336,
+ "height": 188
+ }
+ }
+ },
+ {
+ "player": "youtube",
+ "id": "6niRYcubxPk",
+ "title": "Entornos Interactivos en python",
+ "pubDate": null,
+ "thumbnails": {
+ "default": {
+ "url": "https://i.ytimg.com/vi/6niRYcubxPk/hqdefault.jpg?sqp=-oaymwEbCKgBEF5IVfKriqkDDggBFQAAiEIYAXABwAEG&rs=AOn4CLAxrEGHY_XwWNKcGFaDiyZOpydr8g",
+ "width": 168,
+ "height": 94
+ },
+ "medium": {
+ "url": "https://i.ytimg.com/vi/6niRYcubxPk/hqdefault.jpg?sqp=-oaymwEbCMQBEG5IVfKriqkDDggBFQAAiEIYAXABwAEG&rs=AOn4CLCTuTaZ0CTwp8IZ7pfP4tJ16g-OcA",
+ "width": 196,
+ "height": 110
+ },
+ "high": {
+ "url": "https://i.ytimg.com/vi/6niRYcubxPk/hqdefault.jpg?sqp=-oaymwEcCPYBEIoBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==&rs=AOn4CLAfLBWyvqQzrJs-9pDS_cP02ohAtQ",
+ "width": 246,
+ "height": 138
+ },
+ "standard": {
+ "url": "https://i.ytimg.com/vi/6niRYcubxPk/hqdefault.jpg?sqp=-oaymwEcCNACELwBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==&rs=AOn4CLA1w3xhPuYzyx7hsC_TIWce9lscLw",
+ "width": 336,
+ "height": 188
+ }
+ }
+ },
+ {
+ "player": "youtube",
+ "id": "oMst3JU-RjQ",
+ "title": "Measure all the things",
+ "pubDate": null,
+ "thumbnails": {
+ "default": {
+ "url": "https://i.ytimg.com/vi/oMst3JU-RjQ/hqdefault.jpg?sqp=-oaymwEbCKgBEF5IVfKriqkDDggBFQAAiEIYAXABwAEG&rs=AOn4CLB4BJ8eEBzolMAVDuJJVKkU29CnZQ",
+ "width": 168,
+ "height": 94
+ },
+ "medium": {
+ "url": "https://i.ytimg.com/vi/oMst3JU-RjQ/hqdefault.jpg?sqp=-oaymwEbCMQBEG5IVfKriqkDDggBFQAAiEIYAXABwAEG&rs=AOn4CLAQll3YXDVfl70eJhWtFdwaoDdvEg",
+ "width": 196,
+ "height": 110
+ },
+ "high": {
+ "url": "https://i.ytimg.com/vi/oMst3JU-RjQ/hqdefault.jpg?sqp=-oaymwEcCPYBEIoBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==&rs=AOn4CLDdsXwscRMeenRIajTk7yjkCGjM-g",
+ "width": 246,
+ "height": 138
+ },
+ "standard": {
+ "url": "https://i.ytimg.com/vi/oMst3JU-RjQ/hqdefault.jpg?sqp=-oaymwEcCNACELwBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==&rs=AOn4CLCSpe5sjXUhTGX6yav9iQo7T468nA",
+ "width": 336,
+ "height": 188
+ }
+ }
+ },
+ {
+ "player": "youtube",
+ "id": "D5vmTg95Ov0",
+ "title": "Python 3, Primeros pasos.",
+ "pubDate": null,
+ "thumbnails": {
+ "default": {
+ "url": "https://i.ytimg.com/vi/D5vmTg95Ov0/hqdefault.jpg?sqp=-oaymwE1CKgBEF5IVfKriqkDKAgBFQAAiEIYAXABwAEG8AEB-AH-CYAC0AWKAgwIABABGHIgUihDMA8=&rs=AOn4CLCRsPXxrWLtBm_HYDYsEKR-ZL3i3w",
+ "width": 168,
+ "height": 94
+ },
+ "medium": {
+ "url": "https://i.ytimg.com/vi/D5vmTg95Ov0/hqdefault.jpg?sqp=-oaymwE1CMQBEG5IVfKriqkDKAgBFQAAiEIYAXABwAEG8AEB-AH-CYAC0AWKAgwIABABGHIgUihDMA8=&rs=AOn4CLB1KNClcug1bbL7Lkz848sFdt4XcQ",
+ "width": 196,
+ "height": 110
+ },
+ "high": {
+ "url": "https://i.ytimg.com/vi/D5vmTg95Ov0/hqdefault.jpg?sqp=-oaymwE2CPYBEIoBSFXyq4qpAygIARUAAIhCGAFwAcABBvABAfgB_gmAAtAFigIMCAAQARhyIFIoQzAP&rs=AOn4CLCXA31lYBvrVYYCbH8uMmDOCULMjw",
+ "width": 246,
+ "height": 138
+ },
+ "standard": {
+ "url": "https://i.ytimg.com/vi/D5vmTg95Ov0/hqdefault.jpg?sqp=-oaymwE2CNACELwBSFXyq4qpAygIARUAAIhCGAFwAcABBvABAfgB_gmAAtAFigIMCAAQARhyIFIoQzAP&rs=AOn4CLD8OPfx-iMks95It8zfyyhVoyEkJw",
+ "width": 336,
+ "height": 188
+ }
+ }
+ }
+ ],
+ "eventList": []
+ },
+ "seogalicia": {
+ "name": "Seo Galicia",
+ "logo": "https://vigotech.org/images/seogalicia.png",
+ "links": {
+ "facebook": "https://www.facebook.com/SEOGaliciaMeetup",
+ "meetup": "https://www.meetup.com/es/SEO-Galicia/",
+ "twitter": "https://twitter.com/seo_galicia"
+ },
+ "events": {
+ "type": "meetup",
+ "meetupid": "SEO-Galicia"
+ },
+ "inactive": true,
+ "nextEvent": null,
+ "videoList": [],
+ "eventList": []
+ },
+ "sysadmingalicia": {
+ "name": "SysAdmin Galicia",
+ "logo": "https://vigotech.org/images/sysadmin_galicia.jpg",
+ "links": {
+ "meetup": "https://www.meetup.com/es-ES/Sysadmin-Galicia/",
+ "twitter": "https://twitter.com/sysadmingalicia/"
+ },
+ "events": {
+ "type": "meetup",
+ "meetupid": "Sysadmin-Galicia"
+ },
+ "videos": [
+ {
+ "type": "teltek",
+ "source": "https://replay.teltek.es/podcast/series/58af67c7a7bc283f008b456c/collection.xml"
+ }
+ ],
+ "inactive": true,
+ "nextEvent": null,
+ "videoList": [],
+ "eventList": []
+ },
+ "uxgalicia": {
+ "name": "UX Galicia",
+ "logo": "https://vigotech.org/images/ux_gal.jpg",
+ "links": {
+ "web": "http://www.uxgalicia.com/",
+ "meetup": "https://www.meetup.com/es-ES/Experiencia-de-Usuario-Meetup/",
+ "twitter": "https://twitter.com/uxgalicia/"
+ },
+ "events": {
+ "type": "meetup",
+ "meetupid": "Experiencia-de-Usuario-Meetup"
+ },
+ "inactive": true,
+ "nextEvent": null,
+ "videoList": [],
+ "eventList": []
+ },
+ "vigoadg": {
+ "name": "Vigo Android Developer Group",
+ "logo": "https://vigotech.org/images/vigoadg.jpg",
+ "links": {
+ "twitter": "https://twitter.com/VigoADG",
+ "meetup": "https://www.meetup.com/Vigo-Android-Developer-Group/"
+ },
+ "events": {
+ "type": "meetup",
+ "meetupid": "Vigo-Android-Developer-Group"
+ },
+ "inactive": true,
+ "nextEvent": null,
+ "videoList": [],
+ "eventList": []
+ },
+ "vigojug": {
+ "name": "VigoJUG",
+ "logo": "https://vigotech.org/images/vigojug.jpg",
+ "links": {
+ "web": "http://www.vigojug.org/",
+ "github": "https://github.com/vigojug/",
+ "meetup": "https://www.meetup.com/es-ES/Vigo-JUG/",
+ "twitter": "https://twitter.com/vigojug/",
+ "linkedin": "https://www.linkedin.com/organization/11056204",
+ "youtube": "https://www.youtube.com/channel/UCYSy-eQm6Q02o7WiR6JTqJg",
+ "ivoox": "https://www.ivoox.com/podcast-laretasgeek_sq_f1939875_1.html",
+ "spotify": "https://open.spotify.com/show/2iMpr5Kos3j5YuqB6HfYWL"
+ },
+ "events": {
+ "type": "meetup",
+ "meetupid": "Vigo-JUG"
+ },
+ "videos": [
+ {
+ "type": "youtube",
+ "channel_id": "UCNOihTnorv6dZDANaPXgx_g"
+ },
+ {
+ "type": "youtube",
+ "channel_id": "UCYSy-eQm6Q02o7WiR6JTqJg"
+ }
+ ],
+ "inactive": true,
+ "nextEvent": null,
+ "videoList": [
+ {
+ "player": "youtube",
+ "id": "XE4q7OCBXy8",
+ "title": "Laretas AMA: Telmo Pérez",
+ "pubDate": 1633075094000,
+ "thumbnails": {
+ "default": {
+ "url": "https://i.ytimg.com/vi/XE4q7OCBXy8/default.jpg",
+ "width": 120,
+ "height": 90
+ },
+ "medium": {
+ "url": "https://i.ytimg.com/vi/XE4q7OCBXy8/mqdefault.jpg",
+ "width": 320,
+ "height": 180
+ },
+ "high": {
+ "url": "https://i.ytimg.com/vi/XE4q7OCBXy8/hqdefault.jpg",
+ "width": 480,
+ "height": 360
+ }
+ }
+ },
+ {
+ "player": "youtube",
+ "id": "4WlTqDk0ASM",
+ "title": "Laretas AMA: Agustín Tourón",
+ "pubDate": 1631174511000,
+ "thumbnails": {
+ "default": {
+ "url": "https://i.ytimg.com/vi/4WlTqDk0ASM/default.jpg",
+ "width": 120,
+ "height": 90
+ },
+ "medium": {
+ "url": "https://i.ytimg.com/vi/4WlTqDk0ASM/mqdefault.jpg",
+ "width": 320,
+ "height": 180
+ },
+ "high": {
+ "url": "https://i.ytimg.com/vi/4WlTqDk0ASM/hqdefault.jpg",
+ "width": 480,
+ "height": 360
+ }
+ }
+ },
+ {
+ "player": "youtube",
+ "id": "gqrj-VH7mR8",
+ "title": "Laretas AMA: Fernando Prieto",
+ "pubDate": 1627027803000,
+ "thumbnails": {
+ "default": {
+ "url": "https://i.ytimg.com/vi/gqrj-VH7mR8/default.jpg",
+ "width": 120,
+ "height": 90
+ },
+ "medium": {
+ "url": "https://i.ytimg.com/vi/gqrj-VH7mR8/mqdefault.jpg",
+ "width": 320,
+ "height": 180
+ },
+ "high": {
+ "url": "https://i.ytimg.com/vi/gqrj-VH7mR8/hqdefault.jpg",
+ "width": 480,
+ "height": 360
+ }
+ }
+ },
+ {
+ "player": "youtube",
+ "id": "WHeIAfLsAyw",
+ "title": "Laretas AMA: Miguel Camba",
+ "pubDate": 1625731749000,
+ "thumbnails": {
+ "default": {
+ "url": "https://i.ytimg.com/vi/WHeIAfLsAyw/default.jpg",
+ "width": 120,
+ "height": 90
+ },
+ "medium": {
+ "url": "https://i.ytimg.com/vi/WHeIAfLsAyw/mqdefault.jpg",
+ "width": 320,
+ "height": 180
+ },
+ "high": {
+ "url": "https://i.ytimg.com/vi/WHeIAfLsAyw/hqdefault.jpg",
+ "width": 480,
+ "height": 360
+ }
+ }
+ },
+ {
+ "player": "youtube",
+ "id": "FTsDoh5G2nM",
+ "title": "JReleaser - Liberando a la velocidad de la luz",
+ "pubDate": 1625211411000,
+ "thumbnails": {
+ "default": {
+ "url": "https://i.ytimg.com/vi/FTsDoh5G2nM/default.jpg",
+ "width": 120,
+ "height": 90
+ },
+ "medium": {
+ "url": "https://i.ytimg.com/vi/FTsDoh5G2nM/mqdefault.jpg",
+ "width": 320,
+ "height": 180
+ },
+ "high": {
+ "url": "https://i.ytimg.com/vi/FTsDoh5G2nM/hqdefault.jpg",
+ "width": 480,
+ "height": 360
+ }
+ }
+ },
+ {
+ "player": "youtube",
+ "id": "4vDhL_S_FGA",
+ "title": "Laretas AMA: Cristina Vázquez",
+ "pubDate": 1624004163000,
+ "thumbnails": {
+ "default": {
+ "url": "https://i.ytimg.com/vi/4vDhL_S_FGA/default.jpg",
+ "width": 120,
+ "height": 90
+ },
+ "medium": {
+ "url": "https://i.ytimg.com/vi/4vDhL_S_FGA/mqdefault.jpg",
+ "width": 320,
+ "height": 180
+ },
+ "high": {
+ "url": "https://i.ytimg.com/vi/4vDhL_S_FGA/hqdefault.jpg",
+ "width": 480,
+ "height": 360
+ }
+ }
+ },
+ {
+ "player": "youtube",
+ "id": "K6S9w8iton0",
+ "title": "Laretas AMA: Pilar Vila",
+ "pubDate": 1622880548000,
+ "thumbnails": {
+ "default": {
+ "url": "https://i.ytimg.com/vi/K6S9w8iton0/default.jpg",
+ "width": 120,
+ "height": 90
+ },
+ "medium": {
+ "url": "https://i.ytimg.com/vi/K6S9w8iton0/mqdefault.jpg",
+ "width": 320,
+ "height": 180
+ },
+ "high": {
+ "url": "https://i.ytimg.com/vi/K6S9w8iton0/hqdefault.jpg",
+ "width": 480,
+ "height": 360
+ }
+ }
+ },
+ {
+ "player": "youtube",
+ "id": "Z1NAmxSbLMI",
+ "title": "Laretas Geek - Mayo 2021 - Especial SpringBoot",
+ "pubDate": 1622191197000,
+ "thumbnails": {
+ "default": {
+ "url": "https://i.ytimg.com/vi/Z1NAmxSbLMI/default.jpg",
+ "width": 120,
+ "height": 90
+ },
+ "medium": {
+ "url": "https://i.ytimg.com/vi/Z1NAmxSbLMI/mqdefault.jpg",
+ "width": 320,
+ "height": 180
+ },
+ "high": {
+ "url": "https://i.ytimg.com/vi/Z1NAmxSbLMI/hqdefault.jpg",
+ "width": 480,
+ "height": 360
+ }
+ }
+ },
+ {
+ "player": "youtube",
+ "id": "tx_ji5FTXPQ",
+ "title": "Laretas AMA: Luz Castro",
+ "pubDate": 1621670994000,
+ "thumbnails": {
+ "default": {
+ "url": "https://i.ytimg.com/vi/tx_ji5FTXPQ/default.jpg",
+ "width": 120,
+ "height": 90
+ },
+ "medium": {
+ "url": "https://i.ytimg.com/vi/tx_ji5FTXPQ/mqdefault.jpg",
+ "width": 320,
+ "height": 180
+ },
+ "high": {
+ "url": "https://i.ytimg.com/vi/tx_ji5FTXPQ/hqdefault.jpg",
+ "width": 480,
+ "height": 360
+ }
+ }
+ },
+ {
+ "player": "youtube",
+ "id": "9_zMs-8-01A",
+ "title": "Laretas AMA: André Maneiro",
+ "pubDate": 1620375037000,
+ "thumbnails": {
+ "default": {
+ "url": "https://i.ytimg.com/vi/9_zMs-8-01A/default.jpg",
+ "width": 120,
+ "height": 90
+ },
+ "medium": {
+ "url": "https://i.ytimg.com/vi/9_zMs-8-01A/mqdefault.jpg",
+ "width": 320,
+ "height": 180
+ },
+ "high": {
+ "url": "https://i.ytimg.com/vi/9_zMs-8-01A/hqdefault.jpg",
+ "width": 480,
+ "height": 360
+ }
+ }
+ },
+ {
+ "player": "youtube",
+ "id": "JoKTs_F4PTs",
+ "title": "LaretasGeek - Marzo 2021 - Especial Java 16",
+ "pubDate": 1619771846000,
+ "thumbnails": {
+ "default": {
+ "url": "https://i.ytimg.com/vi/JoKTs_F4PTs/default.jpg",
+ "width": 120,
+ "height": 90
+ },
+ "medium": {
+ "url": "https://i.ytimg.com/vi/JoKTs_F4PTs/mqdefault.jpg",
+ "width": 320,
+ "height": 180
+ },
+ "high": {
+ "url": "https://i.ytimg.com/vi/JoKTs_F4PTs/hqdefault.jpg",
+ "width": 480,
+ "height": 360
+ }
+ }
+ },
+ {
+ "player": "youtube",
+ "id": "7AiU-Wlhlgk",
+ "title": "Laretas AMA: Fran Puga",
+ "pubDate": 1619251491000,
+ "thumbnails": {
+ "default": {
+ "url": "https://i.ytimg.com/vi/7AiU-Wlhlgk/default.jpg",
+ "width": 120,
+ "height": 90
+ },
+ "medium": {
+ "url": "https://i.ytimg.com/vi/7AiU-Wlhlgk/mqdefault.jpg",
+ "width": 320,
+ "height": 180
+ },
+ "high": {
+ "url": "https://i.ytimg.com/vi/7AiU-Wlhlgk/hqdefault.jpg",
+ "width": 480,
+ "height": 360
+ }
+ }
+ },
+ {
+ "player": "youtube",
+ "id": "jvFiG1ukAWc",
+ "title": "Laretas AMA: Antón Román",
+ "pubDate": 1618560349000,
+ "thumbnails": {
+ "default": {
+ "url": "https://i.ytimg.com/vi/jvFiG1ukAWc/default.jpg",
+ "width": 120,
+ "height": 90
+ },
+ "medium": {
+ "url": "https://i.ytimg.com/vi/jvFiG1ukAWc/mqdefault.jpg",
+ "width": 320,
+ "height": 180
+ },
+ "high": {
+ "url": "https://i.ytimg.com/vi/jvFiG1ukAWc/hqdefault.jpg",
+ "width": 480,
+ "height": 360
+ }
+ }
+ },
+ {
+ "player": "youtube",
+ "id": "aJkifnWjug0",
+ "title": "Laretas AMA: Alberto Ruibal",
+ "pubDate": 1617955769000,
+ "thumbnails": {
+ "default": {
+ "url": "https://i.ytimg.com/vi/aJkifnWjug0/default.jpg",
+ "width": 120,
+ "height": 90
+ },
+ "medium": {
+ "url": "https://i.ytimg.com/vi/aJkifnWjug0/mqdefault.jpg",
+ "width": 320,
+ "height": 180
+ },
+ "high": {
+ "url": "https://i.ytimg.com/vi/aJkifnWjug0/hqdefault.jpg",
+ "width": 480,
+ "height": 360
+ }
+ }
+ },
+ {
+ "player": "youtube",
+ "id": "km9YiCqhtps",
+ "title": "Laretas AMA: Eloy Coto",
+ "pubDate": 1617350713000,
+ "thumbnails": {
+ "default": {
+ "url": "https://i.ytimg.com/vi/km9YiCqhtps/default.jpg",
+ "width": 120,
+ "height": 90
+ },
+ "medium": {
+ "url": "https://i.ytimg.com/vi/km9YiCqhtps/mqdefault.jpg",
+ "width": 320,
+ "height": 180
+ },
+ "high": {
+ "url": "https://i.ytimg.com/vi/km9YiCqhtps/hqdefault.jpg",
+ "width": 480,
+ "height": 360
+ }
+ }
+ },
+ {
+ "player": "youtube",
+ "id": "Se0Ov3V11MM",
+ "title": "O sétimo meetup do VigoJUG: Desarrollo de microservicios con Spring Boot",
+ "pubDate": 1513409471000,
+ "thumbnails": {
+ "default": {
+ "url": "https://i.ytimg.com/vi/Se0Ov3V11MM/default.jpg",
+ "width": 120,
+ "height": 90
+ },
+ "medium": {
+ "url": "https://i.ytimg.com/vi/Se0Ov3V11MM/mqdefault.jpg",
+ "width": 320,
+ "height": 180
+ },
+ "high": {
+ "url": "https://i.ytimg.com/vi/Se0Ov3V11MM/hqdefault.jpg",
+ "width": 480,
+ "height": 360
+ }
+ }
+ },
+ {
+ "player": "youtube",
+ "id": "fX1fzZPHaVU",
+ "title": "O sexto meetup do VigoJUG: \"In-Memory Datagrid en arquitecturas de tiempo real\"",
+ "pubDate": 1507057333000,
+ "thumbnails": {
+ "default": {
+ "url": "https://i.ytimg.com/vi/fX1fzZPHaVU/default.jpg",
+ "width": 120,
+ "height": 90
+ },
+ "medium": {
+ "url": "https://i.ytimg.com/vi/fX1fzZPHaVU/mqdefault.jpg",
+ "width": 320,
+ "height": 180
+ },
+ "high": {
+ "url": "https://i.ytimg.com/vi/fX1fzZPHaVU/hqdefault.jpg",
+ "width": 480,
+ "height": 360
+ }
+ }
+ },
+ {
+ "player": "youtube",
+ "id": "8643WerUG-s",
+ "title": "O cuarto meetup do VigoJUG: Kotlin, o Java para o século XXI",
+ "pubDate": 1507016769000,
+ "thumbnails": {
+ "default": {
+ "url": "https://i.ytimg.com/vi/8643WerUG-s/default.jpg",
+ "width": 120,
+ "height": 90
+ },
+ "medium": {
+ "url": "https://i.ytimg.com/vi/8643WerUG-s/mqdefault.jpg",
+ "width": 320,
+ "height": 180
+ },
+ "high": {
+ "url": "https://i.ytimg.com/vi/8643WerUG-s/hqdefault.jpg",
+ "width": 480,
+ "height": 360
+ }
+ }
+ },
+ {
+ "player": "youtube",
+ "id": "4yvSSZMHTZo",
+ "title": "Reactive programming con RxJava",
+ "pubDate": 1493755039000,
+ "thumbnails": {
+ "default": {
+ "url": "https://i.ytimg.com/vi/4yvSSZMHTZo/default.jpg",
+ "width": 120,
+ "height": 90
+ },
+ "medium": {
+ "url": "https://i.ytimg.com/vi/4yvSSZMHTZo/mqdefault.jpg",
+ "width": 320,
+ "height": 180
+ },
+ "high": {
+ "url": "https://i.ytimg.com/vi/4yvSSZMHTZo/hqdefault.jpg",
+ "width": 480,
+ "height": 360
+ }
+ }
+ },
+ {
+ "player": "youtube",
+ "id": "KHdVe9fOa-U",
+ "title": "Introducción de Cassandra con Java",
+ "pubDate": 1493754951000,
+ "thumbnails": {
+ "default": {
+ "url": "https://i.ytimg.com/vi/KHdVe9fOa-U/default.jpg",
+ "width": 120,
+ "height": 90
+ },
+ "medium": {
+ "url": "https://i.ytimg.com/vi/KHdVe9fOa-U/mqdefault.jpg",
+ "width": 320,
+ "height": 180
+ },
+ "high": {
+ "url": "https://i.ytimg.com/vi/KHdVe9fOa-U/hqdefault.jpg",
+ "width": 480,
+ "height": 360
+ }
+ }
+ },
+ {
+ "player": "youtube",
+ "id": "pLsC3jnbX5o",
+ "title": "Emisión en directo de Vigo JUG",
+ "pubDate": 1490819092000,
+ "thumbnails": {
+ "default": {
+ "url": "https://i.ytimg.com/vi/pLsC3jnbX5o/default.jpg",
+ "width": 120,
+ "height": 90
+ },
+ "medium": {
+ "url": "https://i.ytimg.com/vi/pLsC3jnbX5o/mqdefault.jpg",
+ "width": 320,
+ "height": 180
+ },
+ "high": {
+ "url": "https://i.ytimg.com/vi/pLsC3jnbX5o/hqdefault.jpg",
+ "width": 480,
+ "height": 360
+ }
+ }
+ },
+ {
+ "player": "youtube",
+ "id": "smG2P6Esvnc",
+ "title": "\"De Groovy... e Sancho Panza\" por Antón Rodríguez de Optare Solutions 30 min.",
+ "pubDate": 1490818577000,
+ "thumbnails": {
+ "default": {
+ "url": "https://i.ytimg.com/vi/smG2P6Esvnc/default.jpg",
+ "width": 120,
+ "height": 90
+ },
+ "medium": {
+ "url": "https://i.ytimg.com/vi/smG2P6Esvnc/mqdefault.jpg",
+ "width": 320,
+ "height": 180
+ },
+ "high": {
+ "url": "https://i.ytimg.com/vi/smG2P6Esvnc/hqdefault.jpg",
+ "width": 480,
+ "height": 360
+ }
+ }
+ },
+ {
+ "player": "youtube",
+ "id": "PKqTlj38X7M",
+ "title": "Make Java Great Again! por @tomasalmeida de Netcentric. 30 min.",
+ "pubDate": 1490818476000,
+ "thumbnails": {
+ "default": {
+ "url": "https://i.ytimg.com/vi/PKqTlj38X7M/default.jpg",
+ "width": 120,
+ "height": 90
+ },
+ "medium": {
+ "url": "https://i.ytimg.com/vi/PKqTlj38X7M/mqdefault.jpg",
+ "width": 320,
+ "height": 180
+ },
+ "high": {
+ "url": "https://i.ytimg.com/vi/PKqTlj38X7M/hqdefault.jpg",
+ "width": 480,
+ "height": 360
+ }
+ }
+ },
+ {
+ "player": "youtube",
+ "id": "_w_kKWeGct0",
+ "title": "Quarkus World Tour 2021: VigoJUG & CoruñaJUG",
+ "pubDate": null,
+ "thumbnails": {
+ "default": {
+ "url": "https://i.ytimg.com/vi/_w_kKWeGct0/hqdefault.jpg?sqp=-oaymwEbCKgBEF5IVfKriqkDDggBFQAAiEIYAXABwAEG&rs=AOn4CLCyf_qNgK93sRoE1r5itcOTowhORw",
+ "width": 168,
+ "height": 94
+ },
+ "medium": {
+ "url": "https://i.ytimg.com/vi/_w_kKWeGct0/hqdefault.jpg?sqp=-oaymwEbCMQBEG5IVfKriqkDDggBFQAAiEIYAXABwAEG&rs=AOn4CLBR4K0EXuaUOcmPKRg75ehM4mj78w",
+ "width": 196,
+ "height": 110
+ },
+ "high": {
+ "url": "https://i.ytimg.com/vi/_w_kKWeGct0/hqdefault.jpg?sqp=-oaymwEcCPYBEIoBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==&rs=AOn4CLALm-BbHz4_aUN9SVQzksuD3jns6Q",
+ "width": 246,
+ "height": 138
+ },
+ "standard": {
+ "url": "https://i.ytimg.com/vi/_w_kKWeGct0/hqdefault.jpg?sqp=-oaymwEcCNACELwBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==&rs=AOn4CLBFpudfE6cvfbjFFqzWSBiBn-0Z1g",
+ "width": 336,
+ "height": 188
+ }
+ }
+ },
+ {
+ "player": "youtube",
+ "id": "7Q-t_TbUPCs",
+ "title": "Laretas Geek - Marzo 2021 - especial Extreme Programming",
+ "pubDate": null,
+ "thumbnails": {
+ "default": {
+ "url": "https://i.ytimg.com/vi/7Q-t_TbUPCs/hqdefault.jpg?sqp=-oaymwEbCKgBEF5IVfKriqkDDggBFQAAiEIYAXABwAEG&rs=AOn4CLD-ReGFwAEiWBDfsgXu7XCQ7qJegw",
+ "width": 168,
+ "height": 94
+ },
+ "medium": {
+ "url": "https://i.ytimg.com/vi/7Q-t_TbUPCs/hqdefault.jpg?sqp=-oaymwEbCMQBEG5IVfKriqkDDggBFQAAiEIYAXABwAEG&rs=AOn4CLDPDxoT-8jRhl3_KzAS-qjUDCYUyg",
+ "width": 196,
+ "height": 110
+ },
+ "high": {
+ "url": "https://i.ytimg.com/vi/7Q-t_TbUPCs/hqdefault.jpg?sqp=-oaymwEcCPYBEIoBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==&rs=AOn4CLBmEzrXt7VjmINfhHhRpwUoj-ldiQ",
+ "width": 246,
+ "height": 138
+ },
+ "standard": {
+ "url": "https://i.ytimg.com/vi/7Q-t_TbUPCs/hqdefault.jpg?sqp=-oaymwEcCNACELwBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==&rs=AOn4CLDqsTvgIBAlkgmTSoORec0gEq0ZCQ",
+ "width": 336,
+ "height": 188
+ }
+ }
+ },
+ {
+ "player": "youtube",
+ "id": "vYO-e3A9hlg",
+ "title": "Laretas AMA: David García",
+ "pubDate": null,
+ "thumbnails": {
+ "default": {
+ "url": "https://i.ytimg.com/vi/vYO-e3A9hlg/hqdefault.jpg?sqp=-oaymwEbCKgBEF5IVfKriqkDDggBFQAAiEIYAXABwAEG&rs=AOn4CLBWJuFwE6WrhjB7bOydnWLlbN4oAg",
+ "width": 168,
+ "height": 94
+ },
+ "medium": {
+ "url": "https://i.ytimg.com/vi/vYO-e3A9hlg/hqdefault.jpg?sqp=-oaymwEbCMQBEG5IVfKriqkDDggBFQAAiEIYAXABwAEG&rs=AOn4CLDWL-qW-vkogPdG_2nrRSE22gsq6Q",
+ "width": 196,
+ "height": 110
+ },
+ "high": {
+ "url": "https://i.ytimg.com/vi/vYO-e3A9hlg/hqdefault.jpg?sqp=-oaymwEcCPYBEIoBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==&rs=AOn4CLABv6mNEw33xIb08PiIUJuCUk7mqg",
+ "width": 246,
+ "height": 138
+ },
+ "standard": {
+ "url": "https://i.ytimg.com/vi/vYO-e3A9hlg/hqdefault.jpg?sqp=-oaymwEcCNACELwBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==&rs=AOn4CLC035QMMxdGVMkK-9KQW-ITbXgOVA",
+ "width": 336,
+ "height": 188
+ }
+ }
+ },
+ {
+ "player": "youtube",
+ "id": "JL7pEGKda4s",
+ "title": "Laretas AMA: Abdón Rodríguez",
+ "pubDate": null,
+ "thumbnails": {
+ "default": {
+ "url": "https://i.ytimg.com/vi/JL7pEGKda4s/hqdefault.jpg?sqp=-oaymwEbCKgBEF5IVfKriqkDDggBFQAAiEIYAXABwAEG&rs=AOn4CLBNFu2tiJVASpjKoMdKeKdNcABv-Q",
+ "width": 168,
+ "height": 94
+ },
+ "medium": {
+ "url": "https://i.ytimg.com/vi/JL7pEGKda4s/hqdefault.jpg?sqp=-oaymwEbCMQBEG5IVfKriqkDDggBFQAAiEIYAXABwAEG&rs=AOn4CLCT4oeaRt__KA09_HPudfeohTELDg",
+ "width": 196,
+ "height": 110
+ },
+ "high": {
+ "url": "https://i.ytimg.com/vi/JL7pEGKda4s/hqdefault.jpg?sqp=-oaymwEcCPYBEIoBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==&rs=AOn4CLCKmTQ-wuVojDumG8zJElqVVy_u0Q",
+ "width": 246,
+ "height": 138
+ },
+ "standard": {
+ "url": "https://i.ytimg.com/vi/JL7pEGKda4s/hqdefault.jpg?sqp=-oaymwEcCNACELwBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==&rs=AOn4CLDGGMW6OBepdec6NwHuAtqUSAFFQQ",
+ "width": 336,
+ "height": 188
+ }
+ }
+ },
+ {
+ "player": "youtube",
+ "id": "nvHJthOBQ5I",
+ "title": "LaretasGeek - Febrero 2021 - Especial Developer Experience",
+ "pubDate": null,
+ "thumbnails": {
+ "default": {
+ "url": "https://i.ytimg.com/vi/nvHJthOBQ5I/hqdefault.jpg?sqp=-oaymwEbCKgBEF5IVfKriqkDDggBFQAAiEIYAXABwAEG&rs=AOn4CLAWrzdk4l0aDSYD_BkzuvNkq3DkCA",
+ "width": 168,
+ "height": 94
+ },
+ "medium": {
+ "url": "https://i.ytimg.com/vi/nvHJthOBQ5I/hqdefault.jpg?sqp=-oaymwEbCMQBEG5IVfKriqkDDggBFQAAiEIYAXABwAEG&rs=AOn4CLC2kNNCd1jYvz_7gc7fSIHODLQREg",
+ "width": 196,
+ "height": 110
+ },
+ "high": {
+ "url": "https://i.ytimg.com/vi/nvHJthOBQ5I/hqdefault.jpg?sqp=-oaymwEcCPYBEIoBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==&rs=AOn4CLBvS3cPmS1YS7qZlorA6buV_X3wBg",
+ "width": 246,
+ "height": 138
+ },
+ "standard": {
+ "url": "https://i.ytimg.com/vi/nvHJthOBQ5I/hqdefault.jpg?sqp=-oaymwEcCNACELwBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==&rs=AOn4CLDDvfCCgB_6w4G72VCOw6ZyxRII-A",
+ "width": 336,
+ "height": 188
+ }
+ }
+ },
+ {
+ "player": "youtube",
+ "id": "d-K35EeIvcA",
+ "title": "Laretas Geek - Enero 2021 - Especial Elastic",
+ "pubDate": null,
+ "thumbnails": {
+ "default": {
+ "url": "https://i.ytimg.com/vi/d-K35EeIvcA/hqdefault.jpg?sqp=-oaymwEbCKgBEF5IVfKriqkDDggBFQAAiEIYAXABwAEG&rs=AOn4CLAkVEI_3DTcBJkDaeROlB2iAYV6iQ",
+ "width": 168,
+ "height": 94
+ },
+ "medium": {
+ "url": "https://i.ytimg.com/vi/d-K35EeIvcA/hqdefault.jpg?sqp=-oaymwEbCMQBEG5IVfKriqkDDggBFQAAiEIYAXABwAEG&rs=AOn4CLA6E9w2GEied-PR2ddNRBfK6V0cFw",
+ "width": 196,
+ "height": 110
+ },
+ "high": {
+ "url": "https://i.ytimg.com/vi/d-K35EeIvcA/hqdefault.jpg?sqp=-oaymwEcCPYBEIoBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==&rs=AOn4CLCBEBHHtbzDEb6Q4iFEvw9FljFp7w",
+ "width": 246,
+ "height": 138
+ },
+ "standard": {
+ "url": "https://i.ytimg.com/vi/d-K35EeIvcA/hqdefault.jpg?sqp=-oaymwEcCNACELwBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==&rs=AOn4CLCowkGr158d9UZ0jhGNdCs5usqNMg",
+ "width": 336,
+ "height": 188
+ }
+ }
+ },
+ {
+ "player": "youtube",
+ "id": "MewdxXkjgsY",
+ "title": "Laretas Geek - Diciembre 2020 - Especial Java Champions",
+ "pubDate": null,
+ "thumbnails": {
+ "default": {
+ "url": "https://i.ytimg.com/vi/MewdxXkjgsY/hqdefault.jpg?sqp=-oaymwEbCKgBEF5IVfKriqkDDggBFQAAiEIYAXABwAEG&rs=AOn4CLCJGB5dt7VPoSj5bSrONV0Zzfqavg",
+ "width": 168,
+ "height": 94
+ },
+ "medium": {
+ "url": "https://i.ytimg.com/vi/MewdxXkjgsY/hqdefault.jpg?sqp=-oaymwEbCMQBEG5IVfKriqkDDggBFQAAiEIYAXABwAEG&rs=AOn4CLATRJmHbTQFbtruwlWCmT61FQNYfg",
+ "width": 196,
+ "height": 110
+ },
+ "high": {
+ "url": "https://i.ytimg.com/vi/MewdxXkjgsY/hqdefault.jpg?sqp=-oaymwEcCPYBEIoBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==&rs=AOn4CLDcoElb2bOuUU-jdwBCr7FV1Rw7-A",
+ "width": 246,
+ "height": 138
+ },
+ "standard": {
+ "url": "https://i.ytimg.com/vi/MewdxXkjgsY/hqdefault.jpg?sqp=-oaymwEcCNACELwBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==&rs=AOn4CLCjNppF3v1MxoA9hybZIaYirzFDDA",
+ "width": 336,
+ "height": 188
+ }
+ }
+ },
+ {
+ "player": "youtube",
+ "id": "z_4Up8HzjLQ",
+ "title": "Laretas Geek - Noviembre 2020 - Especial Kubernetes",
+ "pubDate": null,
+ "thumbnails": {
+ "default": {
+ "url": "https://i.ytimg.com/vi/z_4Up8HzjLQ/hqdefault.jpg?sqp=-oaymwEbCKgBEF5IVfKriqkDDggBFQAAiEIYAXABwAEG&rs=AOn4CLBwH7mZJVAA57ozD4xSrSgT_pOImw",
+ "width": 168,
+ "height": 94
+ },
+ "medium": {
+ "url": "https://i.ytimg.com/vi/z_4Up8HzjLQ/hqdefault.jpg?sqp=-oaymwEbCMQBEG5IVfKriqkDDggBFQAAiEIYAXABwAEG&rs=AOn4CLBtPbtfbsafHW8fGIds7jy1JkaVfw",
+ "width": 196,
+ "height": 110
+ },
+ "high": {
+ "url": "https://i.ytimg.com/vi/z_4Up8HzjLQ/hqdefault.jpg?sqp=-oaymwEcCPYBEIoBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==&rs=AOn4CLCoNsgBiVmAkYOu4Bl3oyzxbs5e5Q",
+ "width": 246,
+ "height": 138
+ },
+ "standard": {
+ "url": "https://i.ytimg.com/vi/z_4Up8HzjLQ/hqdefault.jpg?sqp=-oaymwEcCNACELwBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==&rs=AOn4CLD7uvNxr6-lWyMFZPAdl3Pjp4mu9A",
+ "width": 336,
+ "height": 188
+ }
+ }
+ },
+ {
+ "player": "youtube",
+ "id": "5BRaPH5BYPY",
+ "title": "Laretas Geek - Octubre 2020 - Especial desarrollo web con Adalab",
+ "pubDate": null,
+ "thumbnails": {
+ "default": {
+ "url": "https://i.ytimg.com/vi/5BRaPH5BYPY/hqdefault.jpg?sqp=-oaymwEbCKgBEF5IVfKriqkDDggBFQAAiEIYAXABwAEG&rs=AOn4CLApF2pgcB-CWM8MqSqW8U_MaAMsXQ",
+ "width": 168,
+ "height": 94
+ },
+ "medium": {
+ "url": "https://i.ytimg.com/vi/5BRaPH5BYPY/hqdefault.jpg?sqp=-oaymwEbCMQBEG5IVfKriqkDDggBFQAAiEIYAXABwAEG&rs=AOn4CLDEGHmNmcMNOrgUiyix2N18dSYNtg",
+ "width": 196,
+ "height": 110
+ },
+ "high": {
+ "url": "https://i.ytimg.com/vi/5BRaPH5BYPY/hqdefault.jpg?sqp=-oaymwEcCPYBEIoBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==&rs=AOn4CLDLE_XgGJ6wyluSHnmnKz1x50DRtg",
+ "width": 246,
+ "height": 138
+ },
+ "standard": {
+ "url": "https://i.ytimg.com/vi/5BRaPH5BYPY/hqdefault.jpg?sqp=-oaymwEcCNACELwBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==&rs=AOn4CLCwgNtsuvu37TXriEGja1wIS2r0kA",
+ "width": 336,
+ "height": 188
+ }
+ }
+ },
+ {
+ "player": "youtube",
+ "id": "L25ryiRmTYQ",
+ "title": "Laretas Geek - Septiembre 2020 - Especial Apache Kafka",
+ "pubDate": null,
+ "thumbnails": {
+ "default": {
+ "url": "https://i.ytimg.com/vi/L25ryiRmTYQ/hqdefault.jpg?sqp=-oaymwEbCKgBEF5IVfKriqkDDggBFQAAiEIYAXABwAEG&rs=AOn4CLAFRqVcerbSYFdzUMtyFLUcw5jmoA",
+ "width": 168,
+ "height": 94
+ },
+ "medium": {
+ "url": "https://i.ytimg.com/vi/L25ryiRmTYQ/hqdefault.jpg?sqp=-oaymwEbCMQBEG5IVfKriqkDDggBFQAAiEIYAXABwAEG&rs=AOn4CLDvetovfJMOfWqukJ3GXsvMDLkFRQ",
+ "width": 196,
+ "height": 110
+ },
+ "high": {
+ "url": "https://i.ytimg.com/vi/L25ryiRmTYQ/hqdefault.jpg?sqp=-oaymwEcCPYBEIoBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==&rs=AOn4CLDHormnage-4yrP1xbhICVTBS8-pw",
+ "width": 246,
+ "height": 138
+ },
+ "standard": {
+ "url": "https://i.ytimg.com/vi/L25ryiRmTYQ/hqdefault.jpg?sqp=-oaymwEcCNACELwBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==&rs=AOn4CLAjVkLSNcgqUAMLHqjDBBWW6kAqew",
+ "width": 336,
+ "height": 188
+ }
+ }
+ },
+ {
+ "player": "youtube",
+ "id": "SHw_MdfmqfA",
+ "title": "Laretas Geek - Agosto 2020 - Especial Comunidades Galicia",
+ "pubDate": null,
+ "thumbnails": {
+ "default": {
+ "url": "https://i.ytimg.com/vi/SHw_MdfmqfA/hqdefault.jpg?sqp=-oaymwEbCKgBEF5IVfKriqkDDggBFQAAiEIYAXABwAEG&rs=AOn4CLAx6cjRpjTLYZ3y8pQ_yiFQETPTdw",
+ "width": 168,
+ "height": 94
+ },
+ "medium": {
+ "url": "https://i.ytimg.com/vi/SHw_MdfmqfA/hqdefault.jpg?sqp=-oaymwEbCMQBEG5IVfKriqkDDggBFQAAiEIYAXABwAEG&rs=AOn4CLAaBmDzSVbOCOcY7ku0lkxrrwI2gg",
+ "width": 196,
+ "height": 110
+ },
+ "high": {
+ "url": "https://i.ytimg.com/vi/SHw_MdfmqfA/hqdefault.jpg?sqp=-oaymwEcCPYBEIoBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==&rs=AOn4CLA96oSvm7J79QOfdW2EpxFMTeKLUw",
+ "width": 246,
+ "height": 138
+ },
+ "standard": {
+ "url": "https://i.ytimg.com/vi/SHw_MdfmqfA/hqdefault.jpg?sqp=-oaymwEcCNACELwBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==&rs=AOn4CLBSv3uSQLAsQ688rabYh22lk11whg",
+ "width": 336,
+ "height": 188
+ }
+ }
+ },
+ {
+ "player": "youtube",
+ "id": "XyZTCy5WQNc",
+ "title": "Laretas Geek - Julio 2020 - Especial Engineering Management",
+ "pubDate": null,
+ "thumbnails": {
+ "default": {
+ "url": "https://i.ytimg.com/vi/XyZTCy5WQNc/hqdefault.jpg?sqp=-oaymwEbCKgBEF5IVfKriqkDDggBFQAAiEIYAXABwAEG&rs=AOn4CLDrPmbFBP-zbSL7TYmEpeuto50Z-Q",
+ "width": 168,
+ "height": 94
+ },
+ "medium": {
+ "url": "https://i.ytimg.com/vi/XyZTCy5WQNc/hqdefault.jpg?sqp=-oaymwEbCMQBEG5IVfKriqkDDggBFQAAiEIYAXABwAEG&rs=AOn4CLApBEtv5HRMoPGFh-Itt67WWMwJ9w",
+ "width": 196,
+ "height": 110
+ },
+ "high": {
+ "url": "https://i.ytimg.com/vi/XyZTCy5WQNc/hqdefault.jpg?sqp=-oaymwEcCPYBEIoBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==&rs=AOn4CLDUZEiHHVCGNwNk-Gw92eWV9uB8GQ",
+ "width": 246,
+ "height": 138
+ },
+ "standard": {
+ "url": "https://i.ytimg.com/vi/XyZTCy5WQNc/hqdefault.jpg?sqp=-oaymwEcCNACELwBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==&rs=AOn4CLA5oaApvgzD8pVCgh4EEmGD3l60Ww",
+ "width": 336,
+ "height": 188
+ }
+ }
+ },
+ {
+ "player": "youtube",
+ "id": "MtcImjBFEj0",
+ "title": "Laretas Geek - Junio 2020 - Mesa redonda 25 años de Java",
+ "pubDate": null,
+ "thumbnails": {
+ "default": {
+ "url": "https://i.ytimg.com/vi/MtcImjBFEj0/hqdefault.jpg?sqp=-oaymwEbCKgBEF5IVfKriqkDDggBFQAAiEIYAXABwAEG&rs=AOn4CLAi-MTlrhg2X1Ww0zuUi493n-QDjA",
+ "width": 168,
+ "height": 94
+ },
+ "medium": {
+ "url": "https://i.ytimg.com/vi/MtcImjBFEj0/hqdefault.jpg?sqp=-oaymwEbCMQBEG5IVfKriqkDDggBFQAAiEIYAXABwAEG&rs=AOn4CLCpeHACrmeUcKq1LksvQnBY7y38LQ",
+ "width": 196,
+ "height": 110
+ },
+ "high": {
+ "url": "https://i.ytimg.com/vi/MtcImjBFEj0/hqdefault.jpg?sqp=-oaymwEcCPYBEIoBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==&rs=AOn4CLAxgFv3u11HOXEuu9dAVWJMenR--g",
+ "width": 246,
+ "height": 138
+ },
+ "standard": {
+ "url": "https://i.ytimg.com/vi/MtcImjBFEj0/hqdefault.jpg?sqp=-oaymwEcCNACELwBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==&rs=AOn4CLCeVKhRaoxSDDhvydu04SPnoA49iA",
+ "width": 336,
+ "height": 188
+ }
+ }
+ }
+ ],
+ "eventList": []
+ },
+ "wppontevedra": {
+ "name": "WordpressPontevedra",
+ "logo": "https://vigotech.org/images/wordpress-pontevedra.png",
+ "links": {
+ "meetup": "https://www.meetup.com/es-ES/Pontevedra-WordPress-Meetup/",
+ "twitter": "https://twitter.com/wppontevedra"
+ },
+ "events": {
+ "type": "meetup",
+ "meetupid": "Pontevedra-WordPress-Meetup"
+ },
+ "inactive": true,
+ "nextEvent": null,
+ "videoList": [],
+ "eventList": []
+ },
+ "vigowordpress": {
+ "name": "VigoWordpress",
+ "logo": "https://vigotech.org/images/vigowordpress.png",
+ "links": {
+ "mail": "wpmeetupvigo@gmail.com",
+ "meetup": "https://www.meetup.com/es-ES/Vigo-WordPress-Meetup/",
+ "twitter": "https://twitter.com/wp_vigo",
+ "youtube": "https://www.youtube.com/channel/UCuipENHgKAhr1VgK59156Tw"
+ },
+ "events": {
+ "type": "meetup",
+ "meetupid": "Vigo-WordPress-Meetup"
+ },
+ "videos": [
+ {
+ "type": "youtube",
+ "channel_id": "UCuipENHgKAhr1VgK59156Tw"
+ }
+ ],
+ "inactive": true,
+ "nextEvent": {
+ "title": "Posicionando sin IA en tiempos de IA",
+ "date": 1774548000000,
+ "url": "https://www.meetup.com/vigo-wordpress-meetup/events/313620908/",
+ "location": "Círculo de Empresarios de Galicia - Rúa de García Barbón, 62, Vigo, Po - Vigo - Po - es"
+ },
+ "videoList": [
+ {
+ "player": "youtube",
+ "id": "IWd72H69Xqo",
+ "title": "Convertir emoción en experiencias digitales",
+ "pubDate": 1772216306000,
+ "thumbnails": {
+ "default": {
+ "url": "https://i.ytimg.com/vi/IWd72H69Xqo/default.jpg",
+ "width": 120,
+ "height": 90
+ },
+ "medium": {
+ "url": "https://i.ytimg.com/vi/IWd72H69Xqo/mqdefault.jpg",
+ "width": 320,
+ "height": 180
+ },
+ "high": {
+ "url": "https://i.ytimg.com/vi/IWd72H69Xqo/hqdefault.jpg",
+ "width": 480,
+ "height": 360
+ }
+ }
+ },
+ {
+ "player": "youtube",
+ "id": "Lu3Cuxdgegw",
+ "title": "Aspectos legales del desarrollo de software",
+ "pubDate": 1771546982000,
+ "thumbnails": {
+ "default": {
+ "url": "https://i.ytimg.com/vi/Lu3Cuxdgegw/default.jpg",
+ "width": 120,
+ "height": 90
+ },
+ "medium": {
+ "url": "https://i.ytimg.com/vi/Lu3Cuxdgegw/mqdefault.jpg",
+ "width": 320,
+ "height": 180
+ },
+ "high": {
+ "url": "https://i.ytimg.com/vi/Lu3Cuxdgegw/hqdefault.jpg",
+ "width": 480,
+ "height": 360
+ }
+ }
+ },
+ {
+ "player": "youtube",
+ "id": "Z7uyExBY9rA",
+ "title": "Haz que te encuentren cómo destacar tu perfil profesional y atraer oportunidades",
+ "pubDate": 1771546621000,
+ "thumbnails": {
+ "default": {
+ "url": "https://i.ytimg.com/vi/Z7uyExBY9rA/default.jpg",
+ "width": 120,
+ "height": 90
+ },
+ "medium": {
+ "url": "https://i.ytimg.com/vi/Z7uyExBY9rA/mqdefault.jpg",
+ "width": 320,
+ "height": 180
+ },
+ "high": {
+ "url": "https://i.ytimg.com/vi/Z7uyExBY9rA/hqdefault.jpg",
+ "width": 480,
+ "height": 360
+ }
+ }
+ },
+ {
+ "player": "youtube",
+ "id": "AXgsnBT9A3M",
+ "title": "Ilustración, cómic y marca identidad ilustrada",
+ "pubDate": 1771546028000,
+ "thumbnails": {
+ "default": {
+ "url": "https://i.ytimg.com/vi/AXgsnBT9A3M/default.jpg",
+ "width": 120,
+ "height": 90
+ },
+ "medium": {
+ "url": "https://i.ytimg.com/vi/AXgsnBT9A3M/mqdefault.jpg",
+ "width": 320,
+ "height": 180
+ },
+ "high": {
+ "url": "https://i.ytimg.com/vi/AXgsnBT9A3M/hqdefault.jpg",
+ "width": 480,
+ "height": 360
+ }
+ }
+ },
+ {
+ "player": "youtube",
+ "id": "O-z_8jx5EOk",
+ "title": "Cómo construir una marca sólida y generar ventas a través del contenido gratuito",
+ "pubDate": 1770665988000,
+ "thumbnails": {
+ "default": {
+ "url": "https://i.ytimg.com/vi/O-z_8jx5EOk/default.jpg",
+ "width": 120,
+ "height": 90
+ },
+ "medium": {
+ "url": "https://i.ytimg.com/vi/O-z_8jx5EOk/mqdefault.jpg",
+ "width": 320,
+ "height": 180
+ },
+ "high": {
+ "url": "https://i.ytimg.com/vi/O-z_8jx5EOk/hqdefault.jpg",
+ "width": 480,
+ "height": 360
+ }
+ }
+ },
+ {
+ "player": "youtube",
+ "id": "x_J_XWR3dwc",
+ "title": "No dejes la puerta abierta ciberseguridad para WordPress",
+ "pubDate": 1759346680000,
+ "thumbnails": {
+ "default": {
+ "url": "https://i.ytimg.com/vi/x_J_XWR3dwc/default.jpg",
+ "width": 120,
+ "height": 90
+ },
+ "medium": {
+ "url": "https://i.ytimg.com/vi/x_J_XWR3dwc/mqdefault.jpg",
+ "width": 320,
+ "height": 180
+ },
+ "high": {
+ "url": "https://i.ytimg.com/vi/x_J_XWR3dwc/hqdefault.jpg",
+ "width": 480,
+ "height": 360
+ }
+ }
+ },
+ {
+ "player": "youtube",
+ "id": "bQhakj6y7-Q",
+ "title": "Factura electrónica vs Verifactu: Diferencias, obligaciones y soluciones",
+ "pubDate": 1755269193000,
+ "thumbnails": {
+ "default": {
+ "url": "https://i.ytimg.com/vi/bQhakj6y7-Q/default.jpg",
+ "width": 120,
+ "height": 90
+ },
+ "medium": {
+ "url": "https://i.ytimg.com/vi/bQhakj6y7-Q/mqdefault.jpg",
+ "width": 320,
+ "height": 180
+ },
+ "high": {
+ "url": "https://i.ytimg.com/vi/bQhakj6y7-Q/hqdefault.jpg",
+ "width": 480,
+ "height": 360
+ }
+ }
+ },
+ {
+ "player": "youtube",
+ "id": "yX79lPGolKU",
+ "title": "IA generativa y marketing real: cómo ahorrar tiempo, vender más y fidelizar mejor",
+ "pubDate": 1748937342000,
+ "thumbnails": {
+ "default": {
+ "url": "https://i.ytimg.com/vi/yX79lPGolKU/default.jpg",
+ "width": 120,
+ "height": 90
+ },
+ "medium": {
+ "url": "https://i.ytimg.com/vi/yX79lPGolKU/mqdefault.jpg",
+ "width": 320,
+ "height": 180
+ },
+ "high": {
+ "url": "https://i.ytimg.com/vi/yX79lPGolKU/hqdefault.jpg",
+ "width": 480,
+ "height": 360
+ }
+ }
+ },
+ {
+ "player": "youtube",
+ "id": "GbqcE-YN7BI",
+ "title": "Creando asistentes virtuales con Inteligencia Artificial",
+ "pubDate": 1740059082000,
+ "thumbnails": {
+ "default": {
+ "url": "https://i.ytimg.com/vi/GbqcE-YN7BI/default.jpg",
+ "width": 120,
+ "height": 90
+ },
+ "medium": {
+ "url": "https://i.ytimg.com/vi/GbqcE-YN7BI/mqdefault.jpg",
+ "width": 320,
+ "height": 180
+ },
+ "high": {
+ "url": "https://i.ytimg.com/vi/GbqcE-YN7BI/hqdefault.jpg",
+ "width": 480,
+ "height": 360
+ }
+ }
+ },
+ {
+ "player": "youtube",
+ "id": "34NKuIcSPSM",
+ "title": "El bienestar corporativo y como multiplicar los resultados de la empresa",
+ "pubDate": 1740058378000,
+ "thumbnails": {
+ "default": {
+ "url": "https://i.ytimg.com/vi/34NKuIcSPSM/default.jpg",
+ "width": 120,
+ "height": 90
+ },
+ "medium": {
+ "url": "https://i.ytimg.com/vi/34NKuIcSPSM/mqdefault.jpg",
+ "width": 320,
+ "height": 180
+ },
+ "high": {
+ "url": "https://i.ytimg.com/vi/34NKuIcSPSM/hqdefault.jpg",
+ "width": 480,
+ "height": 360
+ }
+ }
+ },
+ {
+ "player": "youtube",
+ "id": "YHyx0ao6zCI",
+ "title": "Impacto y experiencia del do_action WCVIGO2024",
+ "pubDate": 1740051769000,
+ "thumbnails": {
+ "default": {
+ "url": "https://i.ytimg.com/vi/YHyx0ao6zCI/default.jpg",
+ "width": 120,
+ "height": 90
+ },
+ "medium": {
+ "url": "https://i.ytimg.com/vi/YHyx0ao6zCI/mqdefault.jpg",
+ "width": 320,
+ "height": 180
+ },
+ "high": {
+ "url": "https://i.ytimg.com/vi/YHyx0ao6zCI/hqdefault.jpg",
+ "width": 480,
+ "height": 360
+ }
+ }
+ },
+ {
+ "player": "youtube",
+ "id": "il_ZCYIgFUo",
+ "title": "Manteniendo la tradición en un eCommerce: Cómo Peperetes preserva lo artesanal",
+ "pubDate": 1723127427000,
+ "thumbnails": {
+ "default": {
+ "url": "https://i.ytimg.com/vi/il_ZCYIgFUo/default.jpg",
+ "width": 120,
+ "height": 90
+ },
+ "medium": {
+ "url": "https://i.ytimg.com/vi/il_ZCYIgFUo/mqdefault.jpg",
+ "width": 320,
+ "height": 180
+ },
+ "high": {
+ "url": "https://i.ytimg.com/vi/il_ZCYIgFUo/hqdefault.jpg",
+ "width": 480,
+ "height": 360
+ }
+ }
+ },
+ {
+ "player": "youtube",
+ "id": "quj83YRodhs",
+ "title": "SEO Local: Cómo ser uno de los tres elegidos de Google",
+ "pubDate": 1711390702000,
+ "thumbnails": {
+ "default": {
+ "url": "https://i.ytimg.com/vi/quj83YRodhs/default.jpg",
+ "width": 120,
+ "height": 90
+ },
+ "medium": {
+ "url": "https://i.ytimg.com/vi/quj83YRodhs/mqdefault.jpg",
+ "width": 320,
+ "height": 180
+ },
+ "high": {
+ "url": "https://i.ytimg.com/vi/quj83YRodhs/hqdefault.jpg",
+ "width": 480,
+ "height": 360
+ }
+ }
+ },
+ {
+ "player": "youtube",
+ "id": "OXqQL7jXCGI",
+ "title": "Green Web diseños web eficientes, optimizados y de transferencia de datos reducida",
+ "pubDate": 1709675437000,
+ "thumbnails": {
+ "default": {
+ "url": "https://i.ytimg.com/vi/OXqQL7jXCGI/default.jpg",
+ "width": 120,
+ "height": 90
+ },
+ "medium": {
+ "url": "https://i.ytimg.com/vi/OXqQL7jXCGI/mqdefault.jpg",
+ "width": 320,
+ "height": 180
+ },
+ "high": {
+ "url": "https://i.ytimg.com/vi/OXqQL7jXCGI/hqdefault.jpg",
+ "width": 480,
+ "height": 360
+ }
+ }
+ },
+ {
+ "player": "youtube",
+ "id": "p4qKYpYDT3s",
+ "title": "Internacionalización de empresas: La era de la exportación digital",
+ "pubDate": 1709255538000,
+ "thumbnails": {
+ "default": {
+ "url": "https://i.ytimg.com/vi/p4qKYpYDT3s/default.jpg",
+ "width": 120,
+ "height": 90
+ },
+ "medium": {
+ "url": "https://i.ytimg.com/vi/p4qKYpYDT3s/mqdefault.jpg",
+ "width": 320,
+ "height": 180
+ },
+ "high": {
+ "url": "https://i.ytimg.com/vi/p4qKYpYDT3s/hqdefault.jpg",
+ "width": 480,
+ "height": 360
+ }
+ }
+ },
+ {
+ "player": "youtube",
+ "id": "cQaMK4jm5Y0",
+ "title": "Los ingredientes de una buena estrategia de DATA DRIVEN en las campañas de publicidad",
+ "pubDate": null,
+ "thumbnails": {
+ "default": {
+ "url": "https://i.ytimg.com/vi/cQaMK4jm5Y0/hqdefault.jpg?sqp=-oaymwE1CKgBEF5IVfKriqkDKAgBFQAAiEIYAXABwAEG8AEB-AH-CYAC0AWKAgwIABABGHIgXyhFMA8=&rs=AOn4CLAVZ6H-HYCkl3a10ELK0VFo1Hkidg",
+ "width": 168,
+ "height": 94
+ },
+ "medium": {
+ "url": "https://i.ytimg.com/vi/cQaMK4jm5Y0/hqdefault.jpg?sqp=-oaymwE1CMQBEG5IVfKriqkDKAgBFQAAiEIYAXABwAEG8AEB-AH-CYAC0AWKAgwIABABGHIgXyhFMA8=&rs=AOn4CLCL_RVApC3uJU6muITIv35JN0lhnw",
+ "width": 196,
+ "height": 110
+ },
+ "high": {
+ "url": "https://i.ytimg.com/vi/cQaMK4jm5Y0/hqdefault.jpg?sqp=-oaymwE2CPYBEIoBSFXyq4qpAygIARUAAIhCGAFwAcABBvABAfgB_gmAAtAFigIMCAAQARhyIF8oRTAP&rs=AOn4CLBEHZt0TMsUN1NELKlvpBhG9l4cuQ",
+ "width": 246,
+ "height": 138
+ },
+ "standard": {
+ "url": "https://i.ytimg.com/vi/cQaMK4jm5Y0/hqdefault.jpg?sqp=-oaymwE2CNACELwBSFXyq4qpAygIARUAAIhCGAFwAcABBvABAfgB_gmAAtAFigIMCAAQARhyIF8oRTAP&rs=AOn4CLCcK9G0CKu3Vh4Vf4vL1HhUE-hD1A",
+ "width": 336,
+ "height": 188
+ }
+ }
+ },
+ {
+ "player": "youtube",
+ "id": "cpGi6sQMbnw",
+ "title": "MeetUp WordPress Vigo 24 10 2023",
+ "pubDate": null,
+ "thumbnails": {
+ "default": {
+ "url": "https://i.ytimg.com/vi/cpGi6sQMbnw/hqdefault.jpg?sqp=-oaymwEbCKgBEF5IVfKriqkDDggBFQAAiEIYAXABwAEG&rs=AOn4CLDPy_Ombm9nu877xhJS7NNl1fY1iQ",
+ "width": 168,
+ "height": 94
+ },
+ "medium": {
+ "url": "https://i.ytimg.com/vi/cpGi6sQMbnw/hqdefault.jpg?sqp=-oaymwEbCMQBEG5IVfKriqkDDggBFQAAiEIYAXABwAEG&rs=AOn4CLBl5Z1TxrJoc_GbhWJr48oyB9jJyA",
+ "width": 196,
+ "height": 110
+ },
+ "high": {
+ "url": "https://i.ytimg.com/vi/cpGi6sQMbnw/hqdefault.jpg?sqp=-oaymwEcCPYBEIoBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==&rs=AOn4CLCvQBrDKeILrWSpS-d0kwT-TVA_1A",
+ "width": 246,
+ "height": 138
+ },
+ "standard": {
+ "url": "https://i.ytimg.com/vi/cpGi6sQMbnw/hqdefault.jpg?sqp=-oaymwEcCNACELwBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==&rs=AOn4CLCMj3Aex_iu0pzOaD8LsSpPCEZR1A",
+ "width": 336,
+ "height": 188
+ }
+ }
+ },
+ {
+ "player": "youtube",
+ "id": "kstyIQqofaE",
+ "title": "Meetup #17 - ¿Tienes un ecommerce y no consigues vender lo que esperabas?",
+ "pubDate": null,
+ "thumbnails": {
+ "default": {
+ "url": "https://i.ytimg.com/vi/kstyIQqofaE/hqdefault.jpg?sqp=-oaymwEbCKgBEF5IVfKriqkDDggBFQAAiEIYAXABwAEG&rs=AOn4CLB2aF5q2SjTDAVZ9kRa5PlYd4818A",
+ "width": 168,
+ "height": 94
+ },
+ "medium": {
+ "url": "https://i.ytimg.com/vi/kstyIQqofaE/hqdefault.jpg?sqp=-oaymwEbCMQBEG5IVfKriqkDDggBFQAAiEIYAXABwAEG&rs=AOn4CLDCFJacGdF1Ee08UigaDbck2s4cyA",
+ "width": 196,
+ "height": 110
+ },
+ "high": {
+ "url": "https://i.ytimg.com/vi/kstyIQqofaE/hqdefault.jpg?sqp=-oaymwEcCPYBEIoBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==&rs=AOn4CLBMKkO21CZjDlDPI8sjNB0lb17oPw",
+ "width": 246,
+ "height": 138
+ },
+ "standard": {
+ "url": "https://i.ytimg.com/vi/kstyIQqofaE/hqdefault.jpg?sqp=-oaymwEcCNACELwBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==&rs=AOn4CLA-ZrQKjmYUytKH-7G0dAG0Gf8_FQ",
+ "width": 336,
+ "height": 188
+ }
+ }
+ },
+ {
+ "player": "youtube",
+ "id": "WN3dyEnpW4M",
+ "title": "Meetup #16 - WebP, un formato para dominarlos a todos",
+ "pubDate": null,
+ "thumbnails": {
+ "default": {
+ "url": "https://i.ytimg.com/vi/WN3dyEnpW4M/hqdefault.jpg?sqp=-oaymwEbCKgBEF5IVfKriqkDDggBFQAAiEIYAXABwAEG&rs=AOn4CLAmwltXbrEbvd-B4tVbXPEoXxMGMA",
+ "width": 168,
+ "height": 94
+ },
+ "medium": {
+ "url": "https://i.ytimg.com/vi/WN3dyEnpW4M/hqdefault.jpg?sqp=-oaymwEbCMQBEG5IVfKriqkDDggBFQAAiEIYAXABwAEG&rs=AOn4CLDLd679C3HM8N5c7XydeUinfyrkCA",
+ "width": 196,
+ "height": 110
+ },
+ "high": {
+ "url": "https://i.ytimg.com/vi/WN3dyEnpW4M/hqdefault.jpg?sqp=-oaymwEcCPYBEIoBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==&rs=AOn4CLCZQIwGMNnwPImExuL7J6wMJ6VpDA",
+ "width": 246,
+ "height": 138
+ },
+ "standard": {
+ "url": "https://i.ytimg.com/vi/WN3dyEnpW4M/hqdefault.jpg?sqp=-oaymwEcCNACELwBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==&rs=AOn4CLAvzeHcEoh0-1FLMUsVQStKcyv-CA",
+ "width": 336,
+ "height": 188
+ }
+ }
+ },
+ {
+ "player": "youtube",
+ "id": "t8ECwCRSlsA",
+ "title": "Meetup #14 - Encuentra y lanza tu idea de negocio",
+ "pubDate": null,
+ "thumbnails": {
+ "default": {
+ "url": "https://i.ytimg.com/vi/t8ECwCRSlsA/hqdefault.jpg?sqp=-oaymwEbCKgBEF5IVfKriqkDDggBFQAAiEIYAXABwAEG&rs=AOn4CLC9F72K0PuasGWqFtIM6FQyFkrLbg",
+ "width": 168,
+ "height": 94
+ },
+ "medium": {
+ "url": "https://i.ytimg.com/vi/t8ECwCRSlsA/hqdefault.jpg?sqp=-oaymwEbCMQBEG5IVfKriqkDDggBFQAAiEIYAXABwAEG&rs=AOn4CLCrzvhapjlxugzWAnhq2bRU6if33Q",
+ "width": 196,
+ "height": 110
+ },
+ "high": {
+ "url": "https://i.ytimg.com/vi/t8ECwCRSlsA/hqdefault.jpg?sqp=-oaymwEcCPYBEIoBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==&rs=AOn4CLAS-SZR3VxRHUuFRFCwmEc4Eh1RJQ",
+ "width": 246,
+ "height": 138
+ },
+ "standard": {
+ "url": "https://i.ytimg.com/vi/t8ECwCRSlsA/hqdefault.jpg?sqp=-oaymwEcCNACELwBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==&rs=AOn4CLAwvpdbyNGrDeD3xQnwObPghLsz3g",
+ "width": 336,
+ "height": 188
+ }
+ }
+ },
+ {
+ "player": "youtube",
+ "id": "RtnOqeCGAKc",
+ "title": "Meetup #13 - Bailaré sobre tu SEO: Google, WordPress y otras historias del punk",
+ "pubDate": null,
+ "thumbnails": {
+ "default": {
+ "url": "https://i.ytimg.com/vi/RtnOqeCGAKc/hqdefault.jpg?sqp=-oaymwEbCKgBEF5IVfKriqkDDggBFQAAiEIYAXABwAEG&rs=AOn4CLDX1MmirOowfBUDDhQC4fs2AHy1VQ",
+ "width": 168,
+ "height": 94
+ },
+ "medium": {
+ "url": "https://i.ytimg.com/vi/RtnOqeCGAKc/hqdefault.jpg?sqp=-oaymwEbCMQBEG5IVfKriqkDDggBFQAAiEIYAXABwAEG&rs=AOn4CLDU5imv_lAZCMduhv0kSj3TxNgLhw",
+ "width": 196,
+ "height": 110
+ },
+ "high": {
+ "url": "https://i.ytimg.com/vi/RtnOqeCGAKc/hqdefault.jpg?sqp=-oaymwEcCPYBEIoBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==&rs=AOn4CLBk53bnu_Ug4roOllRdVushjsIhqg",
+ "width": 246,
+ "height": 138
+ },
+ "standard": {
+ "url": "https://i.ytimg.com/vi/RtnOqeCGAKc/hqdefault.jpg?sqp=-oaymwEcCNACELwBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==&rs=AOn4CLDd1u-ZyqVF64q5eM5nbMqhIeUywg",
+ "width": 336,
+ "height": 188
+ }
+ }
+ },
+ {
+ "player": "youtube",
+ "id": "DjLP6VgNtTU",
+ "title": "Meetup #12 - WooCommerce no es solo una tienda online",
+ "pubDate": null,
+ "thumbnails": {
+ "default": {
+ "url": "https://i.ytimg.com/vi/DjLP6VgNtTU/hqdefault.jpg?sqp=-oaymwEbCKgBEF5IVfKriqkDDggBFQAAiEIYAXABwAEG&rs=AOn4CLAXlLOkVPwChEElESwjjGliwOC_bA",
+ "width": 168,
+ "height": 94
+ },
+ "medium": {
+ "url": "https://i.ytimg.com/vi/DjLP6VgNtTU/hqdefault.jpg?sqp=-oaymwEbCMQBEG5IVfKriqkDDggBFQAAiEIYAXABwAEG&rs=AOn4CLBU7cOilygJeV8brvE2ERXo4VsjKQ",
+ "width": 196,
+ "height": 110
+ },
+ "high": {
+ "url": "https://i.ytimg.com/vi/DjLP6VgNtTU/hqdefault.jpg?sqp=-oaymwEcCPYBEIoBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==&rs=AOn4CLCPkrMF7gJYgX1yDW0O6IR5gbusHw",
+ "width": 246,
+ "height": 138
+ },
+ "standard": {
+ "url": "https://i.ytimg.com/vi/DjLP6VgNtTU/hqdefault.jpg?sqp=-oaymwEcCNACELwBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==&rs=AOn4CLAlOxci9PNsXVYkiCgU6nuYLpQmMQ",
+ "width": 336,
+ "height": 188
+ }
+ }
+ },
+ {
+ "player": "youtube",
+ "id": "L6aSDjE_2Vc",
+ "title": "Meetup #11 - Cómo gestionar una gran cantidad de sitios WordPress",
+ "pubDate": null,
+ "thumbnails": {
+ "default": {
+ "url": "https://i.ytimg.com/vi/L6aSDjE_2Vc/hqdefault.jpg?sqp=-oaymwEbCKgBEF5IVfKriqkDDggBFQAAiEIYAXABwAEG&rs=AOn4CLCL36YmIRseFZC281IAxZjebm9yFQ",
+ "width": 168,
+ "height": 94
+ },
+ "medium": {
+ "url": "https://i.ytimg.com/vi/L6aSDjE_2Vc/hqdefault.jpg?sqp=-oaymwEbCMQBEG5IVfKriqkDDggBFQAAiEIYAXABwAEG&rs=AOn4CLCVVsncMGp4XlVvry1EkdRDKIUbXw",
+ "width": 196,
+ "height": 110
+ },
+ "high": {
+ "url": "https://i.ytimg.com/vi/L6aSDjE_2Vc/hqdefault.jpg?sqp=-oaymwEcCPYBEIoBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==&rs=AOn4CLDomm_QhqQkbL6wsI1JykMKaSirGw",
+ "width": 246,
+ "height": 138
+ },
+ "standard": {
+ "url": "https://i.ytimg.com/vi/L6aSDjE_2Vc/hqdefault.jpg?sqp=-oaymwEcCNACELwBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==&rs=AOn4CLDV6Blw9i5Au2jOWV-qzntyOSEcvQ",
+ "width": 336,
+ "height": 188
+ }
+ }
+ },
+ {
+ "player": "youtube",
+ "id": "wJvxjbGmK9A",
+ "title": "Meetup #10 - ¿Cuánto cuesta una web? Y, ¿como poner en valor mi trabajo?",
+ "pubDate": null,
+ "thumbnails": {
+ "default": {
+ "url": "https://i.ytimg.com/vi/wJvxjbGmK9A/hqdefault.jpg?sqp=-oaymwEbCKgBEF5IVfKriqkDDggBFQAAiEIYAXABwAEG&rs=AOn4CLBiKJ11UtQQpx27ewa5_OylxJ48Ww",
+ "width": 168,
+ "height": 94
+ },
+ "medium": {
+ "url": "https://i.ytimg.com/vi/wJvxjbGmK9A/hqdefault.jpg?sqp=-oaymwEbCMQBEG5IVfKriqkDDggBFQAAiEIYAXABwAEG&rs=AOn4CLCrI28exgQvVWwQ55vSJfuXKLaoTA",
+ "width": 196,
+ "height": 110
+ },
+ "high": {
+ "url": "https://i.ytimg.com/vi/wJvxjbGmK9A/hqdefault.jpg?sqp=-oaymwEcCPYBEIoBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==&rs=AOn4CLAAwNLw_nF7bKOMhpO1LNR0SsVZVg",
+ "width": 246,
+ "height": 138
+ },
+ "standard": {
+ "url": "https://i.ytimg.com/vi/wJvxjbGmK9A/hqdefault.jpg?sqp=-oaymwEcCNACELwBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==&rs=AOn4CLDJQ8m1KRulUybA_sZpsnrpbvqSaA",
+ "width": 336,
+ "height": 188
+ }
+ }
+ },
+ {
+ "player": "youtube",
+ "id": "kPsqFlq9DPQ",
+ "title": "Meetup #09 - Modelo de negocio de un profesional freelance",
+ "pubDate": null,
+ "thumbnails": {
+ "default": {
+ "url": "https://i.ytimg.com/vi/kPsqFlq9DPQ/hqdefault.jpg?sqp=-oaymwEbCKgBEF5IVfKriqkDDggBFQAAiEIYAXABwAEG&rs=AOn4CLBCzftnS9g7duxAIziAwbqTzX0nBQ",
+ "width": 168,
+ "height": 94
+ },
+ "medium": {
+ "url": "https://i.ytimg.com/vi/kPsqFlq9DPQ/hqdefault.jpg?sqp=-oaymwEbCMQBEG5IVfKriqkDDggBFQAAiEIYAXABwAEG&rs=AOn4CLDdJlyjDYnmrOpvqlK96mULEDNlCQ",
+ "width": 196,
+ "height": 110
+ },
+ "high": {
+ "url": "https://i.ytimg.com/vi/kPsqFlq9DPQ/hqdefault.jpg?sqp=-oaymwEcCPYBEIoBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==&rs=AOn4CLBD7fc7GAFASogmd1hQi9TIU0blFA",
+ "width": 246,
+ "height": 138
+ },
+ "standard": {
+ "url": "https://i.ytimg.com/vi/kPsqFlq9DPQ/hqdefault.jpg?sqp=-oaymwEcCNACELwBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==&rs=AOn4CLCo7V6W9LWtw9Rr7uUMmUpUNnaYAQ",
+ "width": 336,
+ "height": 188
+ }
+ }
+ },
+ {
+ "player": "youtube",
+ "id": "oQ-hSvWw4HI",
+ "title": "Meetup #08 - WordPress: Campamento base de tu Marca Personal",
+ "pubDate": null,
+ "thumbnails": {
+ "default": {
+ "url": "https://i.ytimg.com/vi/oQ-hSvWw4HI/hqdefault.jpg?sqp=-oaymwEbCKgBEF5IVfKriqkDDggBFQAAiEIYAXABwAEG&rs=AOn4CLBEOZsPhgQbi0HEaQ-1rBQReZNFFQ",
+ "width": 168,
+ "height": 94
+ },
+ "medium": {
+ "url": "https://i.ytimg.com/vi/oQ-hSvWw4HI/hqdefault.jpg?sqp=-oaymwEbCMQBEG5IVfKriqkDDggBFQAAiEIYAXABwAEG&rs=AOn4CLAXtT87A6emL3KfF1r1clZkroGpxg",
+ "width": 196,
+ "height": 110
+ },
+ "high": {
+ "url": "https://i.ytimg.com/vi/oQ-hSvWw4HI/hqdefault.jpg?sqp=-oaymwEcCPYBEIoBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==&rs=AOn4CLBTDrU7v_CLkWcWDtHwGRPCmT4obA",
+ "width": 246,
+ "height": 138
+ },
+ "standard": {
+ "url": "https://i.ytimg.com/vi/oQ-hSvWw4HI/hqdefault.jpg?sqp=-oaymwEcCNACELwBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==&rs=AOn4CLBpGDmILGD8e7LQ5ugDckc-kgapoA",
+ "width": 336,
+ "height": 188
+ }
+ }
+ },
+ {
+ "player": "youtube",
+ "id": "EVo7vic0b80",
+ "title": "Meetup #07 - ¿Y después qué?",
+ "pubDate": null,
+ "thumbnails": {
+ "default": {
+ "url": "https://i.ytimg.com/vi/EVo7vic0b80/hqdefault.jpg?sqp=-oaymwE1CKgBEF5IVfKriqkDKAgBFQAAiEIYAXABwAEG8AEB-AHUBoAC4AOKAgwIABABGGUgZShlMA8=&rs=AOn4CLAqvd_bHc3eii5giPnjps0JrgWZrA",
+ "width": 168,
+ "height": 94
+ },
+ "medium": {
+ "url": "https://i.ytimg.com/vi/EVo7vic0b80/hqdefault.jpg?sqp=-oaymwE1CMQBEG5IVfKriqkDKAgBFQAAiEIYAXABwAEG8AEB-AHUBoAC4AOKAgwIABABGGUgZShlMA8=&rs=AOn4CLDFu_86Q4f-zCISPqMEvJhZU-hetQ",
+ "width": 196,
+ "height": 110
+ },
+ "high": {
+ "url": "https://i.ytimg.com/vi/EVo7vic0b80/hqdefault.jpg?sqp=-oaymwE2CPYBEIoBSFXyq4qpAygIARUAAIhCGAFwAcABBvABAfgB1AaAAuADigIMCAAQARhlIGUoZTAP&rs=AOn4CLBS7VmrMUDl64rxGqw3nzexVtRh_w",
+ "width": 246,
+ "height": 138
+ },
+ "standard": {
+ "url": "https://i.ytimg.com/vi/EVo7vic0b80/hqdefault.jpg?sqp=-oaymwE2CNACELwBSFXyq4qpAygIARUAAIhCGAFwAcABBvABAfgB1AaAAuADigIMCAAQARhlIGUoZTAP&rs=AOn4CLCBPydnzlMyMCQIKe_KCwbNN8i8oQ",
+ "width": 336,
+ "height": 188
+ }
+ }
+ },
+ {
+ "player": "youtube",
+ "id": "iC-typrnn6U",
+ "title": "Meetup #06 - Dominios y hostings: el interrogatorio",
+ "pubDate": null,
+ "thumbnails": {
+ "default": {
+ "url": "https://i.ytimg.com/vi/iC-typrnn6U/hqdefault.jpg?sqp=-oaymwEbCKgBEF5IVfKriqkDDggBFQAAiEIYAXABwAEG&rs=AOn4CLDApeA8xikkL7Q_bNMX9yiWEmrqmg",
+ "width": 168,
+ "height": 94
+ },
+ "medium": {
+ "url": "https://i.ytimg.com/vi/iC-typrnn6U/hqdefault.jpg?sqp=-oaymwEbCMQBEG5IVfKriqkDDggBFQAAiEIYAXABwAEG&rs=AOn4CLCxphor3SWyrNHX6I7K7nyFNBx4Vg",
+ "width": 196,
+ "height": 110
+ },
+ "high": {
+ "url": "https://i.ytimg.com/vi/iC-typrnn6U/hqdefault.jpg?sqp=-oaymwEcCPYBEIoBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==&rs=AOn4CLAQjF7u3aJNinHJAzQs7SE3os0xDw",
+ "width": 246,
+ "height": 138
+ },
+ "standard": {
+ "url": "https://i.ytimg.com/vi/iC-typrnn6U/hqdefault.jpg?sqp=-oaymwEcCNACELwBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==&rs=AOn4CLBJXQpQG8fyICqjae5sRBKYgDKbMg",
+ "width": 336,
+ "height": 188
+ }
+ }
+ },
+ {
+ "player": "youtube",
+ "id": "KL6cev339Mo",
+ "title": "Meetup #05 - Cómo ser un profesional freelance legal",
+ "pubDate": null,
+ "thumbnails": {
+ "default": {
+ "url": "https://i.ytimg.com/vi/KL6cev339Mo/hqdefault.jpg?sqp=-oaymwEbCKgBEF5IVfKriqkDDggBFQAAiEIYAXABwAEG&rs=AOn4CLBmuI3cMU9WtPMQBroFa0TnSHrJkA",
+ "width": 168,
+ "height": 94
+ },
+ "medium": {
+ "url": "https://i.ytimg.com/vi/KL6cev339Mo/hqdefault.jpg?sqp=-oaymwEbCMQBEG5IVfKriqkDDggBFQAAiEIYAXABwAEG&rs=AOn4CLD05_Ur-xjKz24-oZJ5Ib3LTwE1og",
+ "width": 196,
+ "height": 110
+ },
+ "high": {
+ "url": "https://i.ytimg.com/vi/KL6cev339Mo/hqdefault.jpg?sqp=-oaymwEcCPYBEIoBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==&rs=AOn4CLCLj7Ih8Yx-6VCxFPj2p6EnBLQpzA",
+ "width": 246,
+ "height": 138
+ },
+ "standard": {
+ "url": "https://i.ytimg.com/vi/KL6cev339Mo/hqdefault.jpg?sqp=-oaymwEcCNACELwBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==&rs=AOn4CLBXEbhduoB1uhpqEdNvOxkE0MQKcQ",
+ "width": 336,
+ "height": 188
+ }
+ }
+ },
+ {
+ "player": "youtube",
+ "id": "uMJGN-gTid0",
+ "title": "Meetup #04 - CoP: Comunidades de práctica online",
+ "pubDate": null,
+ "thumbnails": {
+ "default": {
+ "url": "https://i.ytimg.com/vi/uMJGN-gTid0/hqdefault.jpg?sqp=-oaymwEbCKgBEF5IVfKriqkDDggBFQAAiEIYAXABwAEG&rs=AOn4CLCoUlIk7cBmzdwLOayXSjtchYGyZA",
+ "width": 168,
+ "height": 94
+ },
+ "medium": {
+ "url": "https://i.ytimg.com/vi/uMJGN-gTid0/hqdefault.jpg?sqp=-oaymwEbCMQBEG5IVfKriqkDDggBFQAAiEIYAXABwAEG&rs=AOn4CLBOrA5v1JK_Noc7AWQEgczesrfZsg",
+ "width": 196,
+ "height": 110
+ },
+ "high": {
+ "url": "https://i.ytimg.com/vi/uMJGN-gTid0/hqdefault.jpg?sqp=-oaymwEcCPYBEIoBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==&rs=AOn4CLDtqRVV2L0Yw0LgGOA89TlYo_Nxcg",
+ "width": 246,
+ "height": 138
+ },
+ "standard": {
+ "url": "https://i.ytimg.com/vi/uMJGN-gTid0/hqdefault.jpg?sqp=-oaymwEcCNACELwBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==&rs=AOn4CLCt-aJ7w9JMIUIYZ9aMHTutpULMiw",
+ "width": 336,
+ "height": 188
+ }
+ }
+ },
+ {
+ "player": "youtube",
+ "id": "DuJaLqNVVe8",
+ "title": "Meetup #03 - RRSS y su importancia en los negocios digitales",
+ "pubDate": null,
+ "thumbnails": {
+ "default": {
+ "url": "https://i.ytimg.com/vi/DuJaLqNVVe8/hqdefault.jpg?sqp=-oaymwEbCKgBEF5IVfKriqkDDggBFQAAiEIYAXABwAEG&rs=AOn4CLApEhdbU2U0ZvPcp4YRGI26Ip2nWg",
+ "width": 168,
+ "height": 94
+ },
+ "medium": {
+ "url": "https://i.ytimg.com/vi/DuJaLqNVVe8/hqdefault.jpg?sqp=-oaymwEbCMQBEG5IVfKriqkDDggBFQAAiEIYAXABwAEG&rs=AOn4CLCU_zZak3fNz9ivaHNsKaE1gw0IjA",
+ "width": 196,
+ "height": 110
+ },
+ "high": {
+ "url": "https://i.ytimg.com/vi/DuJaLqNVVe8/hqdefault.jpg?sqp=-oaymwEcCPYBEIoBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==&rs=AOn4CLAMhja34ZPn7lURdd2oqddOLo1B6g",
+ "width": 246,
+ "height": 138
+ },
+ "standard": {
+ "url": "https://i.ytimg.com/vi/DuJaLqNVVe8/hqdefault.jpg?sqp=-oaymwEcCNACELwBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==&rs=AOn4CLCZ0YRqSo8gtbhnePXMdJvWpMWAew",
+ "width": 336,
+ "height": 188
+ }
+ }
+ },
+ {
+ "player": "youtube",
+ "id": "0SjwSQqYWQ8",
+ "title": "Meetup #02 - Jerarquía de plantillas, el ABC para desarrollar con WordPress",
+ "pubDate": null,
+ "thumbnails": {
+ "default": {
+ "url": "https://i.ytimg.com/vi/0SjwSQqYWQ8/hqdefault.jpg?sqp=-oaymwEbCKgBEF5IVfKriqkDDggBFQAAiEIYAXABwAEG&rs=AOn4CLB8-F0_0fjTQQykep-PvdjKWn1QJw",
+ "width": 168,
+ "height": 94
+ },
+ "medium": {
+ "url": "https://i.ytimg.com/vi/0SjwSQqYWQ8/hqdefault.jpg?sqp=-oaymwEbCMQBEG5IVfKriqkDDggBFQAAiEIYAXABwAEG&rs=AOn4CLCaq8jTZyBgkyPq-bx-bog-tUtbqw",
+ "width": 196,
+ "height": 110
+ },
+ "high": {
+ "url": "https://i.ytimg.com/vi/0SjwSQqYWQ8/hqdefault.jpg?sqp=-oaymwEcCPYBEIoBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==&rs=AOn4CLCRias8F9o9hsuyccBB3ER-lwS6GQ",
+ "width": 246,
+ "height": 138
+ },
+ "standard": {
+ "url": "https://i.ytimg.com/vi/0SjwSQqYWQ8/hqdefault.jpg?sqp=-oaymwEcCNACELwBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==&rs=AOn4CLBIaVz68Ahto_E3I8ZbT6ohIUCvhg",
+ "width": 336,
+ "height": 188
+ }
+ }
+ },
+ {
+ "player": "youtube",
+ "id": "lLac-qS9fj8",
+ "title": "Meetup #01 - Plugins recomendados para WordPress y cómo crear el tuyo",
+ "pubDate": null,
+ "thumbnails": {
+ "default": {
+ "url": "https://i.ytimg.com/vi/lLac-qS9fj8/hqdefault.jpg?sqp=-oaymwEbCKgBEF5IVfKriqkDDggBFQAAiEIYAXABwAEG&rs=AOn4CLAgApy9PLXVReJ-O3152jyt1RhYGQ",
+ "width": 168,
+ "height": 94
+ },
+ "medium": {
+ "url": "https://i.ytimg.com/vi/lLac-qS9fj8/hqdefault.jpg?sqp=-oaymwEbCMQBEG5IVfKriqkDDggBFQAAiEIYAXABwAEG&rs=AOn4CLCMyc0tVN-qo2wPWd71_82QcpkkAw",
+ "width": 196,
+ "height": 110
+ },
+ "high": {
+ "url": "https://i.ytimg.com/vi/lLac-qS9fj8/hqdefault.jpg?sqp=-oaymwEcCPYBEIoBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==&rs=AOn4CLCCdD0O_s6HP5U-XleD-tm7cfM-3Q",
+ "width": 246,
+ "height": 138
+ },
+ "standard": {
+ "url": "https://i.ytimg.com/vi/lLac-qS9fj8/hqdefault.jpg?sqp=-oaymwEcCNACELwBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==&rs=AOn4CLCI1xCdE7q56DS3Yp2CIwA3YWSNLQ",
+ "width": 336,
+ "height": 188
+ }
+ }
+ }
+ ],
+ "eventList": []
+ }
+ },
+ "nextEvent": null
+}
diff --git a/static/vigotech-schema.json b/public/vigotech-schema.json
similarity index 89%
rename from static/vigotech-schema.json
rename to public/vigotech-schema.json
index caa8a586..edcaa3c1 100644
--- a/static/vigotech-schema.json
+++ b/public/vigotech-schema.json
@@ -4,10 +4,7 @@
"description": "",
"$schema": "http://json-schema.org/draft-04/schema#",
"additionalProperties": false,
- "required": [
- "name",
- "logo"
- ],
+ "required": ["name", "logo"],
"properties": {
"name": {
"type": "string",
@@ -27,10 +24,7 @@
"items": {
"type": "object",
"description": "Link",
- "required": [
- "key",
- "url"
- ],
+ "required": ["key", "url"],
"properties": {
"key": {
"type": "string",
@@ -44,17 +38,12 @@
}
},
"events": {
- "type": [
- "object",
- "array"
- ],
+ "type": ["object", "array"],
"description": "Events data source",
"items": {
"type": "object",
"description": "Event data source",
- "required": [
- "type"
- ],
+ "required": ["type"],
"properties": {
"type": {
"type": "string",
@@ -81,11 +70,7 @@
"items": {
"type": "object",
"description": "Member",
- "required": [
- "key",
- "name",
- "logo"
- ],
+ "required": ["key", "name", "logo"],
"properties": {
"key": {
"type": "string",
@@ -109,10 +94,7 @@
"items": {
"type": "object",
"description": "Link",
- "required": [
- "key",
- "url"
- ],
+ "required": ["key", "url"],
"properties": {
"key": {
"type": "string",
@@ -131,9 +113,7 @@
"items": {
"type": "object",
"description": "Event data source",
- "required": [
- "type"
- ],
+ "required": ["type"],
"properties": {
"type": {
"type": "string",
@@ -154,15 +134,17 @@
}
}
},
+ "inactive": {
+ "type": "boolean",
+ "description": "If true, community is inactive"
+ },
"videos": {
"type": "array",
"description": "Member videos source",
"items": {
"type": "object",
"description": "Member video source",
- "required": [
- "type"
- ],
+ "required": ["type"],
"properties": {
"type": {
"type": "string",
diff --git a/static/vigotech.json b/public/vigotech.json
similarity index 93%
rename from static/vigotech.json
rename to public/vigotech.json
index e61761ed..81c0d7d0 100644
--- a/static/vigotech.json
+++ b/public/vigotech.json
@@ -26,7 +26,8 @@
"type": "meetup",
"meetupid": "agile-vigo"
}
- ]
+ ],
+ "inactive": true
},
"aindustriosa": {
"name": "A Industriosa",
@@ -60,7 +61,8 @@
"events": {
"type": "meetup",
"meetupid": "blockchain_gal_vigo"
- }
+ },
+ "inactive": true
},
"craftersvigo": {
"name": "Crafters Vigo",
@@ -81,6 +83,10 @@
"web": "https://www.galpon.org",
"twitter": "https://twitter.com/galpon",
"maillist": "https://www.galpon.org/content/listas-correo-galpon"
+ },
+ "events": {
+ "type": "json",
+ "source": "https://raw.githubusercontent.com/Daniel-at-github/vigotech_events/refs/heads/main/calendars/obradoiros_galpon.json"
}
},
"galstech": {
@@ -93,7 +99,8 @@
"events": {
"type": "meetup",
"meetupid": "galstech"
- }
+ },
+ "inactive": true
},
"gdgvigo": {
"name": "GDG Vigo",
@@ -114,7 +121,8 @@
"type": "youtube",
"channel_id": "UC3BXzHGAMx7tAgVD1CqCuCQ"
}
- ]
+ ],
+ "inactive": true
},
"joomlavigo": {
"name": "Grupo de Usuarios de Joomla de Vigo",
@@ -150,7 +158,8 @@
"type": "youtube",
"channel_id": "UCzcSOwRc7bfKs9jPehJRNxQ"
}
- ]
+ ],
+ "inactive": true
},
"pythonvigo": {
"name": "PythonVigo",
@@ -183,7 +192,8 @@
"events": {
"type": "meetup",
"meetupid": "SEO-Galicia"
- }
+ },
+ "inactive": true
},
"sysadmingalicia": {
"name": "SysAdmin Galicia",
@@ -201,8 +211,8 @@
"type": "teltek",
"source": "https://replay.teltek.es/podcast/series/58af67c7a7bc283f008b456c/collection.xml"
}
- ]
-
+ ],
+ "inactive": true
},
"uxgalicia": {
"name": "UX Galicia",
@@ -215,7 +225,8 @@
"events": {
"type": "meetup",
"meetupid": "Experiencia-de-Usuario-Meetup"
- }
+ },
+ "inactive": true
},
"vigoadg": {
"name": "Vigo Android Developer Group",
@@ -227,7 +238,8 @@
"events": {
"type": "meetup",
"meetupid": "Vigo-Android-Developer-Group"
- }
+ },
+ "inactive": true
},
"vigojug": {
"name": "VigoJUG",
@@ -255,7 +267,8 @@
"type": "youtube",
"channel_id": "UCYSy-eQm6Q02o7WiR6JTqJg"
}
- ]
+ ],
+ "inactive": true
},
"wppontevedra": {
"name": "WordpressPontevedra",
@@ -267,7 +280,8 @@
"events": {
"type": "meetup",
"meetupid": "Pontevedra-WordPress-Meetup"
- }
+ },
+ "inactive": true
},
"vigowordpress": {
"name": "VigoWordpress",
@@ -287,7 +301,8 @@
"type": "youtube",
"channel_id": "UCuipENHgKAhr1VgK59156Tw"
}
- ]
+ ],
+ "inactive": true
}
}
}
diff --git a/scripts/dev.mjs b/scripts/dev.mjs
new file mode 100644
index 00000000..9faf0caf
--- /dev/null
+++ b/scripts/dev.mjs
@@ -0,0 +1,17 @@
+import { spawn } from 'node:child_process'
+
+const args = process.argv.slice(2)
+const withMockEvents = args.includes('--mockEvents')
+const astroArgs = args.filter((arg) => arg !== '--mockEvents')
+
+const child = spawn('pnpm', ['astro', 'dev', ...astroArgs], {
+ stdio: 'inherit',
+ env: {
+ ...process.env,
+ VIGOTECH_MOCK_EVENTS: withMockEvents ? 'true' : process.env.VIGOTECH_MOCK_EVENTS,
+ },
+})
+
+child.on('exit', (code) => {
+ process.exit(code ?? 0)
+})
diff --git a/scripts/generate-vigotech-json.mjs b/scripts/generate-vigotech-json.mjs
new file mode 100644
index 00000000..c98a7e46
--- /dev/null
+++ b/scripts/generate-vigotech-json.mjs
@@ -0,0 +1,771 @@
+import { mkdir, readFile, writeFile } from 'node:fs/promises'
+import { dirname, resolve } from 'node:path'
+import { fileURLToPath } from 'node:url'
+import { createRequire } from 'node:module'
+
+const require = createRequire(import.meta.url)
+const { Events, Videos, Source } = require('metagroup-schema-tools')
+
+const YOUTUBE_RECENT_VIDEOS_LIMIT = 50
+
+const shouldSuppressLog = (args) => {
+ const text = args
+ .map((arg) => {
+ if (arg instanceof Error) {
+ return `${arg.name} ${arg.message}`
+ }
+
+ if (typeof arg === 'string') {
+ return arg
+ }
+
+ if (arg && typeof arg === 'object' && 'message' in arg && typeof arg.message === 'string') {
+ return String(arg.message)
+ }
+
+ return String(arg)
+ })
+ .join(' ')
+
+ return (
+ text.includes('Server responded to') ||
+ text.includes("Method doesn't allow unregistered callers") ||
+ text.includes('GaxiosError') ||
+ text.includes('Status code 404') ||
+ text.includes('INVALID_AUTH') ||
+ text.includes('Not Found')
+ )
+}
+
+const originalConsoleLog = console.log
+const originalConsoleError = console.error
+
+console.log = (...args) => {
+ if (shouldSuppressLog(args)) {
+ return
+ }
+
+ originalConsoleLog(...args)
+}
+
+console.error = (...args) => {
+ if (shouldSuppressLog(args)) {
+ return
+ }
+
+ originalConsoleError(...args)
+}
+
+const rootDir = resolve(dirname(fileURLToPath(import.meta.url)), '..')
+const publicDir = resolve(rootDir, 'public')
+const contentRootDir = resolve(rootDir, 'src/content')
+const generatedVideosDir = resolve(contentRootDir, 'videos')
+const generatedEventsDir = resolve(contentRootDir, 'events')
+
+const sourceFile = process.env.VIGOTECH_MEMBERS_SOURCE_FILE ?? resolve(publicDir, 'vigotech.json')
+
+const generatedFile =
+ process.env.VIGOTECH_MEMBERS_SOURCE_GENERATED_FILE ??
+ resolve(publicDir, 'vigotech-generated.json')
+
+const schemaFile =
+ process.env.VIGOTECH_MEMBERS_SCHEMA_FILE ?? resolve(publicDir, 'vigotech-schema.json')
+
+const readJson = async (filePath) => JSON.parse(await readFile(filePath, 'utf8'))
+
+const readJsonOrDefault = async (filePath, fallback) => {
+ try {
+ return await readJson(filePath)
+ } catch {
+ return fallback
+ }
+}
+
+const toArray = (value) => {
+ if (!value) {
+ return []
+ }
+
+ return Array.isArray(value) ? value : [value]
+}
+
+const warnFallback = (label, error) => {
+ const message = error instanceof Error ? error.message : String(error)
+ console.warn(`[generate:data] ${label}: ${message}`)
+}
+
+const hasObjectValue = (value) => Boolean(value && typeof value === 'object')
+
+const hasArrayItems = (value) => Array.isArray(value) && value.length > 0
+
+const slugify = (value) =>
+ String(value ?? '')
+ .normalize('NFKD')
+ .replace(/[\u0300-\u036f]/g, '')
+ .toLowerCase()
+ .replace(/[^a-z0-9]+/g, '-')
+ .replace(/(^-|-$)/g, '')
+
+const ensureDirectory = async (directoryPath) => {
+ await mkdir(directoryPath, { recursive: true })
+}
+
+const safeYamlScalar = (value) => JSON.stringify(value ?? '')
+
+const formatFrontmatterValue = (value, indent = 0) => {
+ const prefix = ' '.repeat(indent)
+
+ if (value === null) {
+ return 'null'
+ }
+
+ if (typeof value === 'string') {
+ return safeYamlScalar(value)
+ }
+
+ if (typeof value === 'number' || typeof value === 'boolean') {
+ return String(value)
+ }
+
+ if (Array.isArray(value)) {
+ if (value.length === 0) {
+ return '[]'
+ }
+
+ return value
+ .map((item) => {
+ if (item && typeof item === 'object') {
+ const lines = formatFrontmatterValue(item, indent + 2).split('\n')
+ return `${prefix}- ${lines[0]}${lines.length > 1 ? `\n${lines.slice(1).join('\n')}` : ''}`
+ }
+
+ return `${prefix}- ${formatFrontmatterValue(item, indent + 2)}`
+ })
+ .join('\n')
+ }
+
+ const entries = Object.entries(value)
+ if (entries.length === 0) {
+ return '{}'
+ }
+
+ return entries
+ .map(([key, entryValue]) => {
+ const formatted = formatFrontmatterValue(entryValue, indent + 2)
+ const needsBlock =
+ entryValue !== null &&
+ typeof entryValue === 'object' &&
+ !(Array.isArray(entryValue) && entryValue.length === 0)
+
+ if (needsBlock) {
+ return `${prefix}${key}:\n${formatted}`
+ }
+
+ return `${prefix}${key}: ${formatted}`
+ })
+ .join('\n')
+}
+
+const buildFrontmatterDocument = (data) => `---\n${formatFrontmatterValue(data)}\n---\n`
+
+const getGroupName = (groupId, member) =>
+ typeof member?.name === 'string' && member.name.trim() ? member.name : groupId
+
+const getGroupLogo = (member) => (typeof member?.logo === 'string' ? member.logo : null)
+
+const toContentSlug = (value, fallback) => {
+ const slug = slugify(value)
+ return slug || fallback
+}
+
+const writeIfChanged = async (filePath, content) => {
+ try {
+ const previous = await readFile(filePath, 'utf8')
+ if (previous === content) {
+ return false
+ }
+ } catch {
+ // File does not exist yet.
+ }
+
+ await writeFile(filePath, content)
+ return true
+}
+
+const getVideoId = (video) =>
+ video && typeof video === 'object' && typeof video.id === 'string' && video.id.length > 0
+ ? video.id
+ : null
+
+const combineVideoData = (current, incoming) => {
+ if (!current) {
+ return incoming
+ }
+
+ return {
+ ...current,
+ ...incoming,
+ title: incoming.title ?? current.title,
+ pubDate: incoming.pubDate ?? current.pubDate ?? null,
+ thumbnails: incoming.thumbnails ?? current.thumbnails,
+ }
+}
+
+const mergeVideoLists = (...lists) => {
+ const orderedIds = []
+ const videosById = new Map()
+ const passthroughVideos = []
+
+ for (const list of lists) {
+ if (!Array.isArray(list)) {
+ continue
+ }
+
+ for (const video of list) {
+ const videoId = getVideoId(video)
+
+ if (!videoId) {
+ passthroughVideos.push(video)
+ continue
+ }
+
+ if (!videosById.has(videoId)) {
+ orderedIds.push(videoId)
+ }
+
+ videosById.set(videoId, combineVideoData(videosById.get(videoId), video))
+ }
+ }
+
+ return [...orderedIds.map((videoId) => videosById.get(videoId)), ...passthroughVideos]
+}
+
+const sortVideosByDate = (videos) =>
+ [...videos].sort((a, b) => {
+ const aDate = typeof a?.pubDate === 'number' ? a.pubDate : -1
+ const bDate = typeof b?.pubDate === 'number' ? b.pubDate : -1
+ return bDate - aDate
+ })
+
+const dedupeEvents = (events) => {
+ const orderedIds = []
+ const eventsById = new Map()
+
+ for (const event of events) {
+ if (!event?.sourceId) {
+ continue
+ }
+
+ if (!eventsById.has(event.sourceId)) {
+ orderedIds.push(event.sourceId)
+ }
+
+ eventsById.set(event.sourceId, {
+ ...eventsById.get(event.sourceId),
+ ...event,
+ })
+ }
+
+ return orderedIds.map((id) => eventsById.get(id))
+}
+
+const sortEventsByDate = (events) => [...events].sort((a, b) => a.date - b.date)
+
+const getYoutubeUploadsPlaylistId = (channelId) => {
+ if (typeof channelId !== 'string' || channelId.length < 3 || !channelId.startsWith('UC')) {
+ return null
+ }
+
+ return `UU${channelId.slice(2)}`
+}
+
+const getYoutubeInitialData = async (url) => {
+ const response = await fetch(url, {
+ headers: {
+ 'user-agent':
+ 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/135.0.0.0 Safari/537.36',
+ 'accept-language': 'en-US,en;q=0.9',
+ },
+ })
+
+ if (!response.ok) {
+ throw new Error(`failed to fetch ${url}: ${response.status}`)
+ }
+
+ const html = await response.text()
+ const match = html.match(/var ytInitialData = (\{.*?\});<\/script>/s)
+
+ if (!match) {
+ throw new Error(`ytInitialData not found for ${url}`)
+ }
+
+ return JSON.parse(match[1])
+}
+
+const collectNodesByKey = (value, key, results = []) => {
+ if (Array.isArray(value)) {
+ value.forEach((item) => collectNodesByKey(item, key, results))
+ return results
+ }
+
+ if (!value || typeof value !== 'object') {
+ return results
+ }
+
+ if (key in value) {
+ results.push(value[key])
+ }
+
+ Object.values(value).forEach((item) => collectNodesByKey(item, key, results))
+ return results
+}
+
+const getRendererText = (value) => {
+ if (!value) {
+ return null
+ }
+
+ if (typeof value.simpleText === 'string') {
+ return value.simpleText
+ }
+
+ if (Array.isArray(value.runs)) {
+ return (
+ value.runs
+ .map((run) => run?.text ?? '')
+ .join('')
+ .trim() || null
+ )
+ }
+
+ return null
+}
+
+const normalizeRendererThumbnails = (thumbnailList) => {
+ if (!Array.isArray(thumbnailList) || thumbnailList.length === 0) {
+ return undefined
+ }
+
+ const [defaultThumb, mediumThumb, highThumb, standardThumb = highThumb] = thumbnailList
+
+ return {
+ default: defaultThumb,
+ medium: mediumThumb ?? defaultThumb,
+ high: highThumb ?? mediumThumb ?? defaultThumb,
+ standard: standardThumb ?? highThumb ?? mediumThumb ?? defaultThumb,
+ }
+}
+
+const getYoutubeArchiveVideos = async (channelId) => {
+ const playlistId = getYoutubeUploadsPlaylistId(channelId)
+ if (!playlistId) {
+ return []
+ }
+
+ const initialData = await getYoutubeInitialData(
+ `https://www.youtube.com/playlist?list=${playlistId}`,
+ )
+ const renderers = collectNodesByKey(initialData, 'playlistVideoRenderer')
+
+ return renderers
+ .map((renderer) => {
+ const videoId = typeof renderer?.videoId === 'string' ? renderer.videoId : null
+ if (!videoId) {
+ return null
+ }
+
+ return {
+ player: 'youtube',
+ id: videoId,
+ title: getRendererText(renderer.title) ?? videoId,
+ pubDate: null,
+ thumbnails: normalizeRendererThumbnails(renderer.thumbnail?.thumbnails),
+ }
+ })
+ .filter(Boolean)
+}
+
+const getNextEvent = (member, sources, fallback, label) => {
+ const sourceList = toArray(sources)
+
+ if (
+ sourceList.some((source) => source?.type === 'eventbrite') &&
+ !process.env.EVENTBRITE_OAUTH_TOKEN
+ ) {
+ if (hasObjectValue(fallback)) {
+ warnFallback(`keeping previous nextEvent for ${label}`, 'missing EVENTBRITE_OAUTH_TOKEN')
+ return fallback
+ }
+
+ return null
+ }
+
+ try {
+ const nextEvents = Events.getGroupNextEvents(sourceList, {
+ eventbriteToken: process.env.EVENTBRITE_OAUTH_TOKEN,
+ member,
+ })
+
+ const nextEvent = Array.isArray(nextEvents) ? (nextEvents[0] ?? null) : (nextEvents ?? null)
+
+ if (hasObjectValue(nextEvent)) {
+ return nextEvent
+ }
+
+ if (hasObjectValue(fallback)) {
+ warnFallback(`keeping previous nextEvent for ${label}`, 'no upcoming events fetched')
+ return fallback
+ }
+
+ return null
+ } catch (error) {
+ warnFallback(`using previous nextEvent for ${label}`, error)
+ return fallback ?? null
+ }
+}
+
+const getHistoricalEvents = (member, sources, fallback, label) => {
+ const sourceList = toArray(sources)
+ const fallbackList = Array.isArray(fallback) ? fallback : []
+ const allEvents = []
+
+ for (const source of sourceList) {
+ if (!source?.type) {
+ continue
+ }
+
+ if (source.type === 'eventbrite' && !process.env.EVENTBRITE_OAUTH_TOKEN) {
+ warnFallback(`keeping previous events for ${label}`, 'missing EVENTBRITE_OAUTH_TOKEN')
+ continue
+ }
+
+ try {
+ const nextEvents = toArray(
+ Events.getNextFromSource(source, {
+ eventbriteToken: process.env.EVENTBRITE_OAUTH_TOKEN,
+ member,
+ }),
+ )
+ const prevEvents = toArray(
+ Events.getPrevFromSource(source, {
+ eventbriteToken: process.env.EVENTBRITE_OAUTH_TOKEN,
+ member,
+ }),
+ )
+
+ allEvents.push(...nextEvents, ...prevEvents)
+ } catch (error) {
+ warnFallback(`using previous events for ${label}`, error)
+ }
+ }
+
+ if (allEvents.length === 0 && fallbackList.length > 0) {
+ return fallbackList
+ }
+
+ return dedupeEvents([...allEvents, ...fallbackList])
+}
+
+const getVideoList = async (member, sources, fallback, label) => {
+ const sourceList = toArray(sources)
+
+ try {
+ const videoList = await Videos.getGroupVideos(sourceList, YOUTUBE_RECENT_VIDEOS_LIMIT, {
+ youtubeApiKey: process.env.YOUTUBE_API_KEY,
+ member,
+ })
+
+ const youtubeSources = sourceList.filter(
+ (source) => source?.type === 'youtube' && source?.channel_id,
+ )
+ const youtubeArchiveLists = await Promise.all(
+ youtubeSources.map(async (source) => {
+ try {
+ return await getYoutubeArchiveVideos(source.channel_id)
+ } catch (error) {
+ warnFallback(`using partial youtube archive for ${label}`, error)
+ return []
+ }
+ }),
+ )
+
+ const mergedVideoList = sortVideosByDate(
+ mergeVideoLists(...youtubeArchiveLists, videoList, fallback),
+ )
+
+ if (hasArrayItems(mergedVideoList)) {
+ return mergedVideoList
+ }
+
+ if (hasArrayItems(fallback)) {
+ warnFallback(`keeping previous videoList for ${label}`, 'no videos fetched')
+ return fallback
+ }
+
+ return Array.isArray(videoList) ? videoList : (fallback ?? [])
+ } catch (error) {
+ warnFallback(`using previous videoList for ${label}`, error)
+ return fallback ?? []
+ }
+}
+
+const normalizeVideoEntry = (groupId, groupName, groupLogo, videoRaw, index) => {
+ if (!videoRaw || typeof videoRaw !== 'object') {
+ return null
+ }
+
+ const video = videoRaw
+ const sourceId = (video.id ?? `${groupId}-${String(video.pubDate ?? index)}`).trim()
+ if (!sourceId) {
+ return null
+ }
+
+ const title = video.title ?? `${groupName} video ${index + 1}`
+ const publishedAt =
+ typeof video.pubDate === 'number'
+ ? video.pubDate
+ : typeof video.pubDate === 'string'
+ ? Date.parse(video.pubDate)
+ : null
+
+ const thumbnails = video.thumbnails ?? {}
+ const thumbnail =
+ thumbnails.standard?.url ??
+ thumbnails.high?.url ??
+ thumbnails.medium?.url ??
+ thumbnails.default?.url ??
+ null
+
+ const player = video.player ?? 'youtube'
+ const url =
+ player === 'youtube' ? `https://www.youtube.com/watch?v=${sourceId}` : (video.url ?? null)
+
+ return {
+ sourceId,
+ groupId,
+ groupName,
+ groupLogo,
+ title,
+ player,
+ url,
+ publishedAt: Number.isFinite(publishedAt) ? publishedAt : null,
+ thumbnail,
+ }
+}
+
+const normalizeEventEntry = (groupId, groupName, groupLogo, eventRaw, index) => {
+ if (!eventRaw || typeof eventRaw !== 'object') {
+ return null
+ }
+
+ const title = eventRaw.title ?? eventRaw.name ?? `${groupName} event ${index + 1}`
+ const date =
+ typeof eventRaw.date === 'number'
+ ? eventRaw.date
+ : typeof eventRaw.date === 'string'
+ ? Date.parse(eventRaw.date)
+ : Number.NaN
+
+ if (!Number.isFinite(date)) {
+ return null
+ }
+
+ const sourceId =
+ (eventRaw.sourceId ?? `${groupId}-${date}-${slugify(title)}`).trim() ||
+ `${groupId}-${date}-${index}`
+
+ return {
+ sourceId,
+ groupId,
+ groupName,
+ groupLogo,
+ title,
+ description: eventRaw.description ?? null,
+ date,
+ dateISO: new Date(date).toISOString(),
+ location: eventRaw.location ?? null,
+ link: eventRaw.link ?? eventRaw.url ?? null,
+ }
+}
+
+const getPersistedEventsForMember = (groupId, member) => {
+ const historical = Array.isArray(member.eventList) ? member.eventList : []
+
+ if (historical.length > 0) {
+ return historical
+ }
+
+ const nextEvent = member && typeof member === 'object' ? member.nextEvent : null
+
+ return nextEvent
+ ? [
+ {
+ ...nextEvent,
+ sourceId: `${groupId}-${nextEvent.date ?? 'next'}-${slugify(nextEvent.title ?? 'event')}`,
+ },
+ ]
+ : []
+}
+
+const writeVideoContentFiles = async (members) => {
+ await ensureDirectory(generatedVideosDir)
+
+ let writtenFiles = 0
+
+ for (const [groupId, member] of Object.entries(members)) {
+ const groupName = getGroupName(groupId, member)
+ const groupLogo = getGroupLogo(member)
+ const groupDir = resolve(generatedVideosDir, groupId)
+ await ensureDirectory(groupDir)
+
+ const rawList = Array.isArray(member.videoList) ? member.videoList : []
+ for (const [index, videoRaw] of rawList.entries()) {
+ const video = normalizeVideoEntry(groupId, groupName, groupLogo, videoRaw, index)
+ if (!video) {
+ continue
+ }
+
+ const filePath = resolve(
+ groupDir,
+ `${toContentSlug(video.sourceId, `${groupId}-${index + 1}`)}.md`,
+ )
+ writtenFiles += Number(await writeIfChanged(filePath, buildFrontmatterDocument(video)))
+ }
+ }
+
+ return writtenFiles
+}
+
+const writeEventContentFiles = async (members, historicalEventsByGroup, rootEntry) => {
+ await ensureDirectory(generatedEventsDir)
+
+ let writtenFiles = 0
+
+ if (rootEntry) {
+ const rootDir = resolve(generatedEventsDir, 'root')
+ await ensureDirectory(rootDir)
+ const filePath = resolve(rootDir, `${toContentSlug(rootEntry.sourceId, 'root-next-event')}.md`)
+ writtenFiles += Number(await writeIfChanged(filePath, buildFrontmatterDocument(rootEntry)))
+ }
+
+ for (const [groupId, member] of Object.entries(members)) {
+ const groupName = getGroupName(groupId, member)
+ const groupLogo = getGroupLogo(member)
+ const groupDir = resolve(generatedEventsDir, groupId)
+ await ensureDirectory(groupDir)
+
+ const events =
+ historicalEventsByGroup.get(groupId) ?? getPersistedEventsForMember(groupId, member)
+ for (const [index, eventRaw] of events.entries()) {
+ const event = normalizeEventEntry(groupId, groupName, groupLogo, eventRaw, index)
+ if (!event) {
+ continue
+ }
+
+ const filePath = resolve(
+ groupDir,
+ `${toContentSlug(event.sourceId, `${groupId}-${index + 1}`)}.md`,
+ )
+ writtenFiles += Number(await writeIfChanged(filePath, buildFrontmatterDocument(event)))
+ }
+ }
+
+ return writtenFiles
+}
+
+const main = async () => {
+ const [source, schema, previousGenerated] = await Promise.all([
+ readJson(sourceFile),
+ readJson(schemaFile),
+ readJsonOrDefault(generatedFile, {}),
+ ])
+
+ const validation = Source.validate(source, schema)
+ if (validation.errors.length > 0) {
+ const details = validation.errors
+ .map((error) => `${error.property} ${error.message}`.trim())
+ .join('\n')
+ throw new Error(`Invalid vigotech source data:\n${details}`)
+ }
+
+ const generated = structuredClone(source)
+ generated.nextEvent = getNextEvent(
+ generated,
+ generated.events,
+ previousGenerated.nextEvent ?? null,
+ 'root',
+ )
+
+ const members = generated.members ?? {}
+ const previousMembers = previousGenerated.members ?? {}
+ const historicalEventsByGroup = new Map()
+
+ for (const [memberKey, memberValue] of Object.entries(members)) {
+ if (!memberValue || typeof memberValue !== 'object') {
+ continue
+ }
+
+ const member = memberValue
+ const previousMember = previousMembers[memberKey] ?? {}
+ member.nextEvent = getNextEvent(
+ member,
+ member.events,
+ previousMember.nextEvent ?? null,
+ memberKey,
+ )
+ member.videoList = await getVideoList(
+ member,
+ member.videos,
+ previousMember.videoList ?? [],
+ memberKey,
+ )
+
+ const historicalEvents = sortEventsByDate(
+ getHistoricalEvents(member, member.events, previousMember.eventList ?? [], memberKey),
+ )
+ member.eventList = historicalEvents
+ historicalEventsByGroup.set(memberKey, historicalEvents)
+ if (historicalEvents.length === 0 && member.nextEvent) {
+ historicalEventsByGroup.set(memberKey, getPersistedEventsForMember(memberKey, member))
+ }
+ generated.members[memberKey] = member
+ }
+
+ const rootEventEntry = normalizeEventEntry(
+ 'root',
+ generated.name ?? 'VigoTech Alliance',
+ generated.logo ?? null,
+ generated.nextEvent,
+ 0,
+ )
+ const resolvedRootEventEntry =
+ rootEventEntry ??
+ (generated.nextEvent
+ ? normalizeEventEntry(
+ 'root',
+ generated.name ?? 'VigoTech Alliance',
+ generated.logo ?? null,
+ {
+ ...generated.nextEvent,
+ sourceId: `root-${generated.nextEvent.date ?? 'next'}-${slugify(generated.nextEvent.title ?? 'event')}`,
+ },
+ 0,
+ )
+ : null)
+
+ await ensureDirectory(contentRootDir)
+ const [videoFilesWritten, eventFilesWritten] = await Promise.all([
+ writeVideoContentFiles(members),
+ writeEventContentFiles(members, historicalEventsByGroup, resolvedRootEventEntry),
+ ])
+
+ await writeFile(generatedFile, `${JSON.stringify(generated, null, 2)}\n`)
+ console.log(`Generated ${generatedFile}`)
+ console.log(`Generated ${videoFilesWritten} video content files in ${generatedVideosDir}`)
+ console.log(`Generated ${eventFilesWritten} event content files in ${generatedEventsDir}`)
+}
+
+main().catch((error) => {
+ console.error(error instanceof Error ? error.message : error)
+ process.exit(1)
+})
diff --git a/src/assets/logo.svg b/src/assets/logo.svg
new file mode 100644
index 00000000..78a699b8
--- /dev/null
+++ b/src/assets/logo.svg
@@ -0,0 +1,70 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/components/groups/GroupCard.astro b/src/components/groups/GroupCard.astro
new file mode 100644
index 00000000..bf49e339
--- /dev/null
+++ b/src/components/groups/GroupCard.astro
@@ -0,0 +1,84 @@
+---
+import type { CollectionEntry } from 'astro:content'
+import { Icon } from 'astro-icon/components'
+
+import { LANG } from '../../i18n/config'
+import { groupsT } from '../../i18n/groups'
+import { withBase } from '../../lib/base-path'
+import { getGroupSocialLinks } from '../../lib/vigotech/socials'
+import GroupLogo from '../ui/GroupLogo.astro'
+
+type Props = {
+ group: CollectionEntry<'groups'>
+ compact?: boolean
+ showStatus?: boolean
+}
+
+const { group, compact = false, showStatus = false } = Astro.props
+const t = groupsT[LANG]
+const cardPadding = compact ? 'p-4' : 'p-6'
+const socialLinks = getGroupSocialLinks(group.data.links)
+const cardWidth = 'w-full'
+---
+
+
+ {
+ showStatus &&
+ (group.data.inactive ? (
+
+ {t.inactive}
+
+ ) : (
+
+ {t.active}
+
+ ))
+ }
+
+
+
+
+
+
+
{group.data.name}
+
+ {group.data.videoCount > 0
+ ? `${group.data.videoCount} ${t.videosLabel}`
+ : t.communityLabel}
+
+ {
+ group.data.hasVideos && (
+
+ {t.viewVideos}
+
+ )
+ }
+
+
+
+
+
+
+
+
diff --git a/src/components/groups/GroupsBrowser.astro b/src/components/groups/GroupsBrowser.astro
new file mode 100644
index 00000000..cad026e6
--- /dev/null
+++ b/src/components/groups/GroupsBrowser.astro
@@ -0,0 +1,94 @@
+---
+import type { CollectionEntry } from 'astro:content'
+
+import { LANG } from '../../i18n/config'
+import { groupsT } from '../../i18n/groups'
+import FloatingHeader from '../ui/FloatingHeader.astro'
+import GroupCard from './GroupCard.astro'
+
+type Props = {
+ groups: Array>
+}
+
+const { groups } = Astro.props
+const t = groupsT[LANG]
+
+const filterOptions = [
+ { id: 'active', label: t.filterActive },
+ { id: 'inactive', label: t.filterInactive },
+ { id: 'all', label: t.filterAll },
+]
+---
+
+
+
+
+
+ {
+ groups.map((group) => (
+
+
+
+ ))
+ }
+
+
+ {t.emptyResults}
+
+
+
diff --git a/src/components/home/CalendarSection.astro b/src/components/home/CalendarSection.astro
new file mode 100644
index 00000000..43da7442
--- /dev/null
+++ b/src/components/home/CalendarSection.astro
@@ -0,0 +1,435 @@
+---
+import { LANG, LOCALE } from '../../i18n/config'
+import { calendarT } from '../../i18n/calendar'
+import { withBase } from '../../lib/base-path'
+
+const t = calendarT[LANG]
+const calendarApiUrl = withBase('/api/calendar.json')
+---
+
+
+
+
+
+
+
+
+ chevron_left
+
+
+
+ chevron_right
+
+
+
+
+
+
{t.loading}
+
{t.error}
+
+
+
+
+
+
+
diff --git a/src/components/home/ConversationSection.astro b/src/components/home/ConversationSection.astro
new file mode 100644
index 00000000..77f0dec7
--- /dev/null
+++ b/src/components/home/ConversationSection.astro
@@ -0,0 +1,75 @@
+---
+import { Icon } from 'astro-icon/components'
+
+import { LANG } from '../../i18n/config'
+import { homeConversationT } from '../../i18n/home-conversation'
+import { withBase } from '../../lib/base-path'
+import ConversationShader from '../shaders/ConversationShader.astro'
+
+const t = homeConversationT[LANG]
+
+const socialItems = [
+ { key: 'twitter', icon: 'lucide:twitter' },
+ { key: 'telegram', icon: 'lucide:send' },
+ { key: 'email', icon: 'lucide:mail' },
+ { key: 'github', icon: 'lucide:github' },
+] as const
+---
+
+
diff --git a/src/components/home/DocumentsSection.astro b/src/components/home/DocumentsSection.astro
new file mode 100644
index 00000000..d2f78bfc
--- /dev/null
+++ b/src/components/home/DocumentsSection.astro
@@ -0,0 +1,28 @@
+---
+import type { CollectionEntry } from 'astro:content'
+
+import { withBase } from '../../lib/base-path'
+
+type Props = {
+ docs: Array>
+}
+
+const { docs } = Astro.props
+---
+
+
diff --git a/src/components/home/FriendsSection.astro b/src/components/home/FriendsSection.astro
new file mode 100644
index 00000000..e0167fa1
--- /dev/null
+++ b/src/components/home/FriendsSection.astro
@@ -0,0 +1,36 @@
+---
+import type { CollectionEntry } from 'astro:content'
+import { LANG } from '../../i18n/config'
+import { homeFriendsT } from '../../i18n/home-friends'
+import { withBase } from '../../lib/base-path'
+
+type Props = {
+ friends: Array>
+}
+
+const { friends } = Astro.props
+const t = homeFriendsT[LANG]
+---
+
+{
+ friends.length > 0 && (
+
+ )
+}
diff --git a/src/components/home/GroupsSection.astro b/src/components/home/GroupsSection.astro
new file mode 100644
index 00000000..925e10cc
--- /dev/null
+++ b/src/components/home/GroupsSection.astro
@@ -0,0 +1,38 @@
+---
+import type { CollectionEntry } from 'astro:content'
+
+import { LANG } from '../../i18n/config'
+import { groupsT } from '../../i18n/groups'
+import GroupCard from '../groups/GroupCard.astro'
+
+type Props = {
+ groups: Array>
+}
+
+const { groups } = Astro.props
+const t = groupsT[LANG]
+---
+
+
+
+
+
+ {t.activeHeading}
+
+
+
+
+ {
+ groups.map((group) => (
+
+ ))
+ }
+
+
+
diff --git a/src/components/home/HeroSection.astro b/src/components/home/HeroSection.astro
new file mode 100644
index 00000000..a1631d98
--- /dev/null
+++ b/src/components/home/HeroSection.astro
@@ -0,0 +1,96 @@
+---
+import type { CollectionEntry } from 'astro:content'
+
+import { LANG } from '../../i18n/config'
+import { homeHeroT } from '../../i18n/home-hero'
+import HeroShader from '../shaders/HeroShader.astro'
+import GroupLogo from '../ui/GroupLogo.astro'
+import UpcomingEventsPanel from './UpcomingEventsPanel.astro'
+
+type Props = {
+ featuredGroups: Array>
+ totalGroups: number
+ upcomingEvents: Array>
+}
+
+const { featuredGroups, totalGroups, upcomingEvents } = Astro.props
+const t = homeHeroT[LANG]
+
+const escapeHtml = (value: string): string =>
+ value
+ .replace(/&/g, '&')
+ .replace(//g, '>')
+ .replace(/"/g, '"')
+ .replace(/'/g, ''')
+
+const renderTitleMarkdown = (value: string): string => {
+ const escaped = escapeHtml(value)
+
+ return escaped
+ .replace(
+ /\*\*(.+?)\*\*/g,
+ '$1 ',
+ )
+ .replace(/\n/g, ' ')
+}
+
+const titleHtml = renderTitleMarkdown(t.titleMarkdown)
+---
+
+
+
+
+
+
+
+
+
+
+ {t.description}
+
+
+
+ {t.exploreButton}
+
+
+ {
+ featuredGroups
+ .slice(0, 3)
+ .map((group) => (
+
+ ))
+ }
+
+ +{totalGroups}
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/components/home/UpcomingEventsPanel.astro b/src/components/home/UpcomingEventsPanel.astro
new file mode 100644
index 00000000..3e21cc85
--- /dev/null
+++ b/src/components/home/UpcomingEventsPanel.astro
@@ -0,0 +1,82 @@
+---
+import type { CollectionEntry } from 'astro:content'
+
+import { LANG } from '../../i18n/config'
+import { homeHeroT } from '../../i18n/home-hero'
+import UpcomingEventCard from './upcoming-event-card/UpcomingEventCard.astro'
+
+type Props = {
+ upcomingEvents: Array>
+}
+
+const { upcomingEvents } = Astro.props
+const t = homeHeroT[LANG]
+
+const nowWithBuffer = Date.now() - 2 * 60 * 60 * 1000
+const activeUpcomingEvents = upcomingEvents.filter(
+ (event) => event.data.date >= nowWithBuffer,
+)
+---
+
+{
+ activeUpcomingEvents.length > 0 && (
+
+
+
+
+ {t.upcomingEvents} ({activeUpcomingEvents.length})
+
+
+
+ {activeUpcomingEvents.map((event) => (
+
+
+
+ ))}
+
+
+
+ )
+}
+
+
diff --git a/src/components/home/VideosSection.astro b/src/components/home/VideosSection.astro
new file mode 100644
index 00000000..8c611f4b
--- /dev/null
+++ b/src/components/home/VideosSection.astro
@@ -0,0 +1,87 @@
+---
+import type { CollectionEntry } from 'astro:content'
+
+import { LANG, LOCALE } from '../../i18n/config'
+import { homeVideosT } from '../../i18n/home-videos'
+import { withBase } from '../../lib/base-path'
+import GroupLogo from '../ui/GroupLogo.astro'
+
+type Props = {
+ videos: Array>
+}
+
+const { videos } = Astro.props
+const t = homeVideosT[LANG]
+
+const formatDate = (value: number | null): string => {
+ if (!value) {
+ return ''
+ }
+ return new Intl.DateTimeFormat(LOCALE, {
+ year: 'numeric',
+ month: 'short',
+ day: '2-digit',
+ })
+ .format(new Date(value))
+ .replace(/\./g, '')
+}
+---
+
+
diff --git a/src/components/home/upcoming-event-card/UpcomingEventCard.astro b/src/components/home/upcoming-event-card/UpcomingEventCard.astro
new file mode 100644
index 00000000..c77727d9
--- /dev/null
+++ b/src/components/home/upcoming-event-card/UpcomingEventCard.astro
@@ -0,0 +1,34 @@
+---
+import type { CollectionEntry } from 'astro:content'
+
+import { LANG } from '../../../i18n/config'
+import { homeHeroT } from '../../../i18n/home-hero'
+import UpcomingEventCardContent from './UpcomingEventCardContent.astro'
+
+type Props = {
+ event: CollectionEntry<'events'>
+}
+
+const { event } = Astro.props
+const t = homeHeroT[LANG]
+
+const cardClass =
+ 'block rounded-lg bg-white/40 p-3 text-ink-contrast transition-transform hover:-translate-y-0.5'
+---
+
+{
+ event.data.link ? (
+
+
+
+ ) : (
+
+
+
+ )
+}
diff --git a/src/components/home/upcoming-event-card/UpcomingEventCardContent.astro b/src/components/home/upcoming-event-card/UpcomingEventCardContent.astro
new file mode 100644
index 00000000..57c3626a
--- /dev/null
+++ b/src/components/home/upcoming-event-card/UpcomingEventCardContent.astro
@@ -0,0 +1,93 @@
+---
+import type { CollectionEntry } from 'astro:content'
+
+import { LOCALE } from '../../../i18n/config'
+import GroupLogo from '../../ui/GroupLogo.astro'
+
+type Props = {
+ event: CollectionEntry<'events'>
+ ctaLabel?: string
+}
+
+const { event, ctaLabel } = Astro.props
+
+const formatMonthShort = (dateValue: number): string =>
+ new Intl.DateTimeFormat(LOCALE, {
+ month: 'short',
+ })
+ .format(new Date(dateValue))
+ .replace(/\./g, '')
+
+const formatTime = (dateValue: number): string =>
+ new Intl.DateTimeFormat(LOCALE, {
+ hour: '2-digit',
+ minute: '2-digit',
+ })
+ .format(new Date(dateValue))
+ .replace(/\./g, '')
+---
+
+
+
+
+
+
+
+
+ {event.data.groupName}
+
+
+ {event.data.title}
+
+
+
+ {
+ event.data.location && (
+
+ {event.data.location}
+
+ )
+ }
+
+
+
+
+
+ {
+ new Intl.DateTimeFormat(LOCALE, {
+ day: '2-digit',
+ }).format(new Date(event.data.date))
+ }
+
+
+ {formatMonthShort(event.data.date)}
+
+
+
+ {formatTime(event.data.date)}
+
+
+
+
+{
+ ctaLabel && (
+
+ {ctaLabel}
+
+ )
+}
diff --git a/src/components/layout/Footer.astro b/src/components/layout/Footer.astro
new file mode 100644
index 00000000..69a7678b
--- /dev/null
+++ b/src/components/layout/Footer.astro
@@ -0,0 +1,42 @@
+---
+import Logo from '../../assets/logo.svg'
+import { LANG } from '../../i18n/config'
+import { footerT } from '../../i18n/footer'
+import { withBase } from '../../lib/base-path'
+
+const t = footerT[LANG]
+---
+
+
diff --git a/src/components/layout/Header.astro b/src/components/layout/Header.astro
new file mode 100644
index 00000000..8d663130
--- /dev/null
+++ b/src/components/layout/Header.astro
@@ -0,0 +1,172 @@
+---
+import Logo from '../../assets/logo.svg'
+import { menuItems } from '../../config/menu'
+import { LANG } from '../../i18n/config'
+import { headerT } from '../../i18n/header'
+import { stripBase, withBase } from '../../lib/base-path'
+import ThemeToggle from '../theme/ThemeToggle.astro'
+
+const t = headerT[LANG]
+
+const normalizePath = (value: string): string => {
+ if (value === '/') {
+ return '/'
+ }
+ return value.replace(/\/+$/, '')
+}
+
+const currentPath = normalizePath(stripBase(Astro.url.pathname))
+
+const isActiveUrl = (url: string): boolean => {
+ const target = normalizePath(url)
+
+ if (target === '/') {
+ return currentPath === '/'
+ }
+
+ return currentPath === target || currentPath.startsWith(`${target}/`)
+}
+---
+
+
+
+
+
+
+
+
diff --git a/src/components/shaders/ConversationShader.astro b/src/components/shaders/ConversationShader.astro
new file mode 100644
index 00000000..d4d07178
--- /dev/null
+++ b/src/components/shaders/ConversationShader.astro
@@ -0,0 +1,73 @@
+
+
+
diff --git a/src/components/shaders/HeroShader.astro b/src/components/shaders/HeroShader.astro
new file mode 100644
index 00000000..77fe94db
--- /dev/null
+++ b/src/components/shaders/HeroShader.astro
@@ -0,0 +1,109 @@
+
+
+
diff --git a/src/components/theme/ThemeScript.astro b/src/components/theme/ThemeScript.astro
new file mode 100644
index 00000000..9dfa4bb3
--- /dev/null
+++ b/src/components/theme/ThemeScript.astro
@@ -0,0 +1,14 @@
+
diff --git a/src/components/theme/ThemeToggle.astro b/src/components/theme/ThemeToggle.astro
new file mode 100644
index 00000000..03f880ea
--- /dev/null
+++ b/src/components/theme/ThemeToggle.astro
@@ -0,0 +1,64 @@
+---
+import { Icon } from 'astro-icon/components'
+import { LANG } from '../../i18n/config'
+import { themeToggleT } from '../../i18n/theme-toggle'
+
+const t = themeToggleT[LANG]
+---
+
+
+
+
+ {t.darkMode}
+
+
+
diff --git a/src/components/ui/FloatingHeader.astro b/src/components/ui/FloatingHeader.astro
new file mode 100644
index 00000000..783e5f02
--- /dev/null
+++ b/src/components/ui/FloatingHeader.astro
@@ -0,0 +1,412 @@
+---
+type FilterOption = {
+ id: string
+ label: string
+}
+
+type Props = {
+ eyebrow?: string
+ title: string
+ searchPlaceholder?: string
+ filters?: FilterOption[]
+ activeFilterId?: string
+ searchValue?: string
+ threshold?: number
+ eventName?: string
+ showControls?: boolean
+}
+
+const {
+ eyebrow,
+ title,
+ searchPlaceholder = '',
+ filters = [],
+ activeFilterId = '',
+ searchValue = '',
+ threshold = 0,
+ eventName,
+ showControls = true,
+} = Astro.props
+
+const escapeHtml = (value: string): string =>
+ value
+ .replace(/&/g, '&')
+ .replace(//g, '>')
+ .replace(/"/g, '"')
+ .replace(/'/g, ''')
+
+const renderMarkdownInline = (value: string): string =>
+ escapeHtml(value).replace(
+ /\*\*(.+?)\*\*/g,
+ '$1 ',
+ )
+
+const titleHtml = renderMarkdownInline(title)
+---
+
+
+
+
+
+
+ {
+ eyebrow && (
+
+ {eyebrow}
+
+ )
+ }
+
+
+
+ {
+ showControls ? (
+
+
+
+
+
+ Filtros
+
+ tune
+
+
+
+
+
+
+ ) : (
+
+
+
+ )
+ }
+
+
+
+
+
+
+
+
+
diff --git a/src/components/ui/GroupLogo.astro b/src/components/ui/GroupLogo.astro
new file mode 100644
index 00000000..5be5cb20
--- /dev/null
+++ b/src/components/ui/GroupLogo.astro
@@ -0,0 +1,47 @@
+---
+import { withBase } from '../../lib/base-path'
+
+type Props = {
+ src: string | null
+ name: string
+ sizeClass?: string
+ class?: string
+ fallbackClass?: string
+}
+
+const {
+ src,
+ name,
+ sizeClass = 'size-10',
+ class: customClass = '',
+ fallbackClass = 'text-xs font-semibold text-[var(--ink)]',
+} = Astro.props
+
+const initials = name
+ .split(/\s+/)
+ .filter(Boolean)
+ .slice(0, 2)
+ .map((part) => part[0])
+ .join('')
+ .toUpperCase()
+
+const resolvedSrc = src ? withBase(src) : null
+---
+
+{
+ resolvedSrc ? (
+
+ ) : (
+
+ {initials || 'VT'}
+
+ )
+}
diff --git a/src/components/videos/VideosBrowser.astro b/src/components/videos/VideosBrowser.astro
new file mode 100644
index 00000000..10705e05
--- /dev/null
+++ b/src/components/videos/VideosBrowser.astro
@@ -0,0 +1,182 @@
+---
+import type { CollectionEntry } from 'astro:content'
+
+import { LANG, LOCALE } from '../../i18n/config'
+import { videosBrowserT } from '../../i18n/videos-browser'
+import { withBase } from '../../lib/base-path'
+import FloatingHeader from '../ui/FloatingHeader.astro'
+import GroupLogo from '../ui/GroupLogo.astro'
+
+type Props = {
+ videos: Array>
+ groups: Array>
+}
+
+const { videos, groups } = Astro.props
+
+const sortedGroups = [...groups]
+ .filter((group) => group.data.videoCount > 0)
+ .sort((a, b) => a.data.name.localeCompare(b.data.name, LOCALE))
+
+const t = videosBrowserT[LANG]
+
+const filterOptions = [
+ { id: 'all', label: t.allGroups },
+ ...sortedGroups.map((group) => ({ id: group.id, label: group.data.name })),
+]
+
+const formatDate = (value: number | null): string => {
+ if (!value) {
+ return ''
+ }
+ return new Intl.DateTimeFormat(LOCALE, {
+ year: 'numeric',
+ month: 'short',
+ day: '2-digit',
+ })
+ .format(new Date(value))
+ .replace(/\./g, '')
+}
+---
+
+
+
+
+
+
+ {t.emptyResults}
+
+
+
diff --git a/src/config/menu.ts b/src/config/menu.ts
new file mode 100644
index 00000000..974d36cb
--- /dev/null
+++ b/src/config/menu.ts
@@ -0,0 +1,11 @@
+export type MenuItem = {
+ id: 'groups' | 'videos' | 'about' | 'home'
+ url: string
+}
+
+export const menuItems: MenuItem[] = [
+ { id: 'home', url: '/' },
+ { id: 'groups', url: '/groups' },
+ { id: 'videos', url: '/videos' },
+ { id: 'about', url: '/manifesto' },
+]
diff --git a/src/content.config.ts b/src/content.config.ts
new file mode 100644
index 00000000..72e83779
--- /dev/null
+++ b/src/content.config.ts
@@ -0,0 +1,178 @@
+import { glob } from 'astro/loaders'
+import { defineCollection } from 'astro:content'
+import { z } from 'astro/zod'
+
+import { documentSources } from './lib/vigotech/documents'
+import { loadVigotechSources, slugify, toLocalGroupLogo } from './lib/vigotech/source'
+
+const groups = defineCollection({
+ loader: async () => {
+ const { source, generated } = await loadVigotechSources()
+ const sourceMembers = source.members ?? {}
+ const generatedMembers = generated.members ?? {}
+ const keys = new Set([...Object.keys(sourceMembers), ...Object.keys(generatedMembers)])
+
+ return [...keys].map((key) => {
+ const fromSource = sourceMembers[key] ?? {}
+ const fromGenerated = generatedMembers[key] ?? {}
+ const sourceLinks = (fromSource.links ?? {}) as Record
+ const generatedLinks = (fromGenerated.links ?? {}) as Record
+ const links = { ...sourceLinks, ...generatedLinks }
+ const name =
+ ((fromGenerated.name as string | undefined) ??
+ (fromSource.name as string | undefined) ??
+ key) ||
+ key
+ const videoList = fromGenerated.videoList
+ const videoCount = Array.isArray(videoList)
+ ? videoList.length
+ : videoList && typeof videoList === 'object'
+ ? Object.keys(videoList as Record).length
+ : 0
+ return {
+ id: key,
+ key,
+ slug: slugify(key),
+ name,
+ logo: toLocalGroupLogo(
+ (fromGenerated.logo as string | undefined) ??
+ (fromSource.logo as string | undefined) ??
+ null,
+ ),
+ links,
+ inactive:
+ (fromSource.inactive as boolean | undefined) ??
+ (fromGenerated.inactive as boolean | undefined) ??
+ false,
+ hasVideos: videoCount > 0,
+ videoCount,
+ }
+ })
+ },
+ schema: z.object({
+ key: z.string(),
+ slug: z.string(),
+ name: z.string(),
+ logo: z.string().nullable(),
+ links: z.record(z.string(), z.string()).default({}),
+ inactive: z.boolean().default(false),
+ hasVideos: z.boolean(),
+ videoCount: z.number(),
+ }),
+})
+
+const events = defineCollection({
+ loader: glob({ pattern: '**/*.md', base: './src/content/events' }),
+ schema: z.object({
+ sourceId: z.string(),
+ groupId: z.string(),
+ groupName: z.string(),
+ groupLogo: z.string().nullable(),
+ title: z.string(),
+ description: z.string().nullable(),
+ date: z.number(),
+ dateISO: z.string(),
+ location: z.string().nullable(),
+ link: z.string().nullable(),
+ }),
+})
+
+const videos = defineCollection({
+ loader: glob({ pattern: '**/*.md', base: './src/content/videos' }),
+ schema: z.object({
+ sourceId: z.string(),
+ groupId: z.string(),
+ groupName: z.string(),
+ groupLogo: z.string().nullable(),
+ title: z.string(),
+ player: z.string(),
+ url: z.string().nullable(),
+ publishedAt: z.number().nullable(),
+ thumbnail: z.string().nullable(),
+ }),
+})
+
+const friends = defineCollection({
+ loader: async () => {
+ const { friends } = await loadVigotechSources()
+
+ if (Array.isArray(friends)) {
+ return friends.map((item, index) => {
+ const friend = item as Record
+ const name = (friend.name as string | undefined) ?? `Friend ${index + 1}`
+ return {
+ id: slugify(name) || `friend-${index + 1}`,
+ name,
+ logo: (friend.logo as string | undefined) ?? null,
+ link: (friend.link as string | undefined) ?? (friend.web as string | undefined) ?? null,
+ }
+ })
+ }
+
+ return Object.entries(friends).map(([key, value]) => {
+ const friend = (value ?? {}) as Record
+ const name = ((friend.name as string | undefined) ?? key) || key
+ return {
+ id: slugify(key) || key,
+ name,
+ logo: (friend.logo as string | undefined) ?? null,
+ link: (friend.link as string | undefined) ?? (friend.web as string | undefined) ?? null,
+ }
+ })
+ },
+ schema: z.object({
+ name: z.string(),
+ logo: z.string().nullable(),
+ link: z.string().nullable(),
+ }),
+})
+
+const documents = defineCollection({
+ loader: {
+ name: 'vigotech-documents-loader',
+ load: async ({ store, parseData, renderMarkdown }) => {
+ store.clear()
+
+ for (const document of documentSources) {
+ let markdown = `# ${document.title}\n\nSource unavailable during build.`
+
+ try {
+ const response = await fetch(document.url)
+ if (response.ok) {
+ markdown = await response.text()
+ }
+ } catch {
+ // Keep fallback content
+ }
+
+ const data = await parseData({
+ id: document.id,
+ data: {
+ title: document.title,
+ slug: document.slug,
+ sourceUrl: document.url,
+ },
+ })
+
+ store.set({
+ id: document.id,
+ data,
+ rendered: await renderMarkdown(markdown),
+ })
+ }
+ },
+ },
+ schema: z.object({
+ title: z.string(),
+ slug: z.string(),
+ sourceUrl: z.string().url(),
+ }),
+})
+
+export const collections = {
+ groups,
+ events,
+ videos,
+ friends,
+ documents,
+}
diff --git a/src/content/events/pythonvigo/pythonvigo-1671130800000-reunion-diciembre-2022.md b/src/content/events/pythonvigo/pythonvigo-1671130800000-reunion-diciembre-2022.md
new file mode 100644
index 00000000..a84cb35c
--- /dev/null
+++ b/src/content/events/pythonvigo/pythonvigo-1671130800000-reunion-diciembre-2022.md
@@ -0,0 +1,12 @@
+---
+sourceId: 'pythonvigo-1671130800000-reunion-diciembre-2022'
+groupId: 'pythonvigo'
+groupName: 'PythonVigo'
+groupLogo: 'https://vigotech.org/images/python_vigo.png'
+title: 'Reunión Diciembre 2022'
+description: null
+date: 1671130800000
+dateISO: '2022-12-15T19:00:00.000Z'
+location: 'Cafe UF'
+link: 'https://www.python-vigo.es/posts/reunion-diciembre-2022/'
+---
diff --git a/src/content/events/vigowordpress/vigowordpress-1774548000000-posicionando-sin-ia-en-tiempos-de-ia.md b/src/content/events/vigowordpress/vigowordpress-1774548000000-posicionando-sin-ia-en-tiempos-de-ia.md
new file mode 100644
index 00000000..f47e381d
--- /dev/null
+++ b/src/content/events/vigowordpress/vigowordpress-1774548000000-posicionando-sin-ia-en-tiempos-de-ia.md
@@ -0,0 +1,12 @@
+---
+sourceId: 'vigowordpress-1774548000000-posicionando-sin-ia-en-tiempos-de-ia'
+groupId: 'vigowordpress'
+groupName: 'VigoWordpress'
+groupLogo: 'https://vigotech.org/images/vigowordpress.png'
+title: 'Posicionando sin IA en tiempos de IA'
+description: null
+date: 1774548000000
+dateISO: '2026-03-26T18:00:00.000Z'
+location: 'Círculo de Empresarios de Galicia - Rúa de García Barbón, 62, Vigo, Po - Vigo - Po - es'
+link: 'https://www.meetup.com/vigo-wordpress-meetup/events/313620908/'
+---
diff --git a/src/content/videos/aindustriosa/33xt39a-cec.md b/src/content/videos/aindustriosa/33xt39a-cec.md
new file mode 100644
index 00000000..422b4e01
--- /dev/null
+++ b/src/content/videos/aindustriosa/33xt39a-cec.md
@@ -0,0 +1,11 @@
+---
+sourceId: '33Xt39a_cEc'
+groupId: 'aindustriosa'
+groupName: 'A Industriosa'
+groupLogo: 'https://vigotech.org/images/aindustriosa.png'
+title: '20250322 - Galegos na FOSDEM - José María Casanova'
+player: 'youtube'
+url: 'https://www.youtube.com/watch?v=33Xt39a_cEc'
+publishedAt: 1743146003000
+thumbnail: 'https://i.ytimg.com/vi/33Xt39a_cEc/hqdefault.jpg'
+---
diff --git a/src/content/videos/aindustriosa/37xmhgwkuae.md b/src/content/videos/aindustriosa/37xmhgwkuae.md
new file mode 100644
index 00000000..95dd81b7
--- /dev/null
+++ b/src/content/videos/aindustriosa/37xmhgwkuae.md
@@ -0,0 +1,11 @@
+---
+sourceId: '37xmhGWKuAE'
+groupId: 'aindustriosa'
+groupName: 'A Industriosa'
+groupLogo: 'https://vigotech.org/images/aindustriosa.png'
+title: '23012019 - Un repaso a las competiciones de robots siguelíneas'
+player: 'youtube'
+url: 'https://www.youtube.com/watch?v=37xmhGWKuAE'
+publishedAt: null
+thumbnail: 'https://i.ytimg.com/vi/37xmhGWKuAE/hqdefault.jpg?sqp=-oaymwEcCNACELwBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==&rs=AOn4CLBKo89lg2gwrPN4IzxVDxFHMR__RA'
+---
diff --git a/src/content/videos/aindustriosa/50trtscnuis.md b/src/content/videos/aindustriosa/50trtscnuis.md
new file mode 100644
index 00000000..f9946dcc
--- /dev/null
+++ b/src/content/videos/aindustriosa/50trtscnuis.md
@@ -0,0 +1,11 @@
+---
+sourceId: '50TrtscnUis'
+groupId: 'aindustriosa'
+groupName: 'A Industriosa'
+groupLogo: 'https://vigotech.org/images/aindustriosa.png'
+title: '20210227 - Ultracasa 3000'
+player: 'youtube'
+url: 'https://www.youtube.com/watch?v=50TrtscnUis'
+publishedAt: null
+thumbnail: 'https://i.ytimg.com/vi/50TrtscnUis/hqdefault.jpg?sqp=-oaymwEcCNACELwBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==&rs=AOn4CLB8S3u6LnzGnDm7MQcvlcoN7FUCvg'
+---
diff --git a/src/content/videos/aindustriosa/7mvk7obsv80.md b/src/content/videos/aindustriosa/7mvk7obsv80.md
new file mode 100644
index 00000000..c3703d92
--- /dev/null
+++ b/src/content/videos/aindustriosa/7mvk7obsv80.md
@@ -0,0 +1,11 @@
+---
+sourceId: '7mVK7obSv80'
+groupId: 'aindustriosa'
+groupName: 'A Industriosa'
+groupLogo: 'https://vigotech.org/images/aindustriosa.png'
+title: 'A Industriosa - Promo'
+player: 'youtube'
+url: 'https://www.youtube.com/watch?v=7mVK7obSv80'
+publishedAt: null
+thumbnail: 'https://i.ytimg.com/vi/7mVK7obSv80/hqdefault.jpg?sqp=-oaymwEcCNACELwBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==&rs=AOn4CLCtK_cXRX8dm3oAGd6bfbhMNe35Aw'
+---
diff --git a/src/content/videos/aindustriosa/7okgu70odti.md b/src/content/videos/aindustriosa/7okgu70odti.md
new file mode 100644
index 00000000..833fc80e
--- /dev/null
+++ b/src/content/videos/aindustriosa/7okgu70odti.md
@@ -0,0 +1,11 @@
+---
+sourceId: '7oKgu70oDtI'
+groupId: 'aindustriosa'
+groupName: 'A Industriosa'
+groupLogo: 'https://vigotech.org/images/aindustriosa.png'
+title: '20180601 - Garabullo - Diego Lale'
+player: 'youtube'
+url: 'https://www.youtube.com/watch?v=7oKgu70oDtI'
+publishedAt: null
+thumbnail: 'https://i.ytimg.com/vi/7oKgu70oDtI/hqdefault.jpg?sqp=-oaymwEcCNACELwBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==&rs=AOn4CLBbBtvCzM9Qx8TnJtZ5aGBvJQDktA'
+---
diff --git a/src/content/videos/aindustriosa/9ga8hhu1dig.md b/src/content/videos/aindustriosa/9ga8hhu1dig.md
new file mode 100644
index 00000000..ffa730c4
--- /dev/null
+++ b/src/content/videos/aindustriosa/9ga8hhu1dig.md
@@ -0,0 +1,11 @@
+---
+sourceId: '9Ga8hHu1Dig'
+groupId: 'aindustriosa'
+groupName: 'A Industriosa'
+groupLogo: 'https://vigotech.org/images/aindustriosa.png'
+title: '20190304 - Charla ganadores Regata Solar 2018 categoría Open'
+player: 'youtube'
+url: 'https://www.youtube.com/watch?v=9Ga8hHu1Dig'
+publishedAt: null
+thumbnail: 'https://i.ytimg.com/vi/9Ga8hHu1Dig/hqdefault.jpg?sqp=-oaymwEcCNACELwBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==&rs=AOn4CLCWGqqYhQoCQpTOfQ3m_gTFV_cG7w'
+---
diff --git a/src/content/videos/aindustriosa/9p2kho8rjw0.md b/src/content/videos/aindustriosa/9p2kho8rjw0.md
new file mode 100644
index 00000000..8e30dcd1
--- /dev/null
+++ b/src/content/videos/aindustriosa/9p2kho8rjw0.md
@@ -0,0 +1,11 @@
+---
+sourceId: '9p2kho8RJW0'
+groupId: 'aindustriosa'
+groupName: 'A Industriosa'
+groupLogo: 'https://vigotech.org/images/aindustriosa.png'
+title: '20230414 - Rural Hackers'
+player: 'youtube'
+url: 'https://www.youtube.com/watch?v=9p2kho8RJW0'
+publishedAt: 1681596391000
+thumbnail: 'https://i.ytimg.com/vi/9p2kho8RJW0/hqdefault.jpg'
+---
diff --git a/src/content/videos/aindustriosa/9u0djwikyga.md b/src/content/videos/aindustriosa/9u0djwikyga.md
new file mode 100644
index 00000000..a1a5c812
--- /dev/null
+++ b/src/content/videos/aindustriosa/9u0djwikyga.md
@@ -0,0 +1,11 @@
+---
+sourceId: '9U0djWiKyGA'
+groupId: 'aindustriosa'
+groupName: 'A Industriosa'
+groupLogo: 'https://vigotech.org/images/aindustriosa.png'
+title: '20250322 - Galegos na FOSDEM - David de la Iglesia'
+player: 'youtube'
+url: 'https://www.youtube.com/watch?v=9U0djWiKyGA'
+publishedAt: 1743146051000
+thumbnail: 'https://i.ytimg.com/vi/9U0djWiKyGA/hqdefault.jpg'
+---
diff --git a/src/content/videos/aindustriosa/b6erbdjfbwg.md b/src/content/videos/aindustriosa/b6erbdjfbwg.md
new file mode 100644
index 00000000..c31c4088
--- /dev/null
+++ b/src/content/videos/aindustriosa/b6erbdjfbwg.md
@@ -0,0 +1,11 @@
+---
+sourceId: 'b6ErBdjfBWg'
+groupId: 'aindustriosa'
+groupName: 'A Industriosa'
+groupLogo: 'https://vigotech.org/images/aindustriosa.png'
+title: '20190227 - Cómo construirte una impresora 3d XXL'
+player: 'youtube'
+url: 'https://www.youtube.com/watch?v=b6ErBdjfBWg'
+publishedAt: null
+thumbnail: 'https://i.ytimg.com/vi/b6ErBdjfBWg/hqdefault.jpg?sqp=-oaymwEcCNACELwBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==&rs=AOn4CLAybyN4extkcliKgLPu9uEEgznWPw'
+---
diff --git a/src/content/videos/aindustriosa/bmmg6o0i4ei.md b/src/content/videos/aindustriosa/bmmg6o0i4ei.md
new file mode 100644
index 00000000..1751b537
--- /dev/null
+++ b/src/content/videos/aindustriosa/bmmg6o0i4ei.md
@@ -0,0 +1,11 @@
+---
+sourceId: 'bmMG6O0I4eI'
+groupId: 'aindustriosa'
+groupName: 'A Industriosa'
+groupLogo: 'https://vigotech.org/images/aindustriosa.png'
+title: '20200801 - [LIVE] - Hackeando mi robot aspirador'
+player: 'youtube'
+url: 'https://www.youtube.com/watch?v=bmMG6O0I4eI'
+publishedAt: null
+thumbnail: 'https://i.ytimg.com/vi/bmMG6O0I4eI/hqdefault.jpg?sqp=-oaymwEcCNACELwBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==&rs=AOn4CLBp5SdOh3_cKYYGqZkRs-DlI7hbjw'
+---
diff --git a/src/content/videos/aindustriosa/br0vvthan6o.md b/src/content/videos/aindustriosa/br0vvthan6o.md
new file mode 100644
index 00000000..f42da7f4
--- /dev/null
+++ b/src/content/videos/aindustriosa/br0vvthan6o.md
@@ -0,0 +1,11 @@
+---
+sourceId: 'bR0vVThAn6o'
+groupId: 'aindustriosa'
+groupName: 'A Industriosa'
+groupLogo: 'https://vigotech.org/images/aindustriosa.png'
+title: 'A Industriosa no telexornal da TVG'
+player: 'youtube'
+url: 'https://www.youtube.com/watch?v=bR0vVThAn6o'
+publishedAt: null
+thumbnail: 'https://i.ytimg.com/vi/bR0vVThAn6o/hqdefault.jpg?sqp=-oaymwEcCNACELwBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==&rs=AOn4CLDmVkXC4cBphwFVcTwhGGy1jEBRXA'
+---
diff --git a/src/content/videos/aindustriosa/crs2ofs-aqw.md b/src/content/videos/aindustriosa/crs2ofs-aqw.md
new file mode 100644
index 00000000..c08990b1
--- /dev/null
+++ b/src/content/videos/aindustriosa/crs2ofs-aqw.md
@@ -0,0 +1,11 @@
+---
+sourceId: 'cRS2oFs_aqw'
+groupId: 'aindustriosa'
+groupName: 'A Industriosa'
+groupLogo: 'https://vigotech.org/images/aindustriosa.png'
+title: 'A Industriosa en Localia'
+player: 'youtube'
+url: 'https://www.youtube.com/watch?v=cRS2oFs_aqw'
+publishedAt: null
+thumbnail: 'https://i.ytimg.com/vi/cRS2oFs_aqw/hqdefault.jpg?sqp=-oaymwEcCNACELwBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==&rs=AOn4CLBkYHA8xH3O1-EAuSWkEo-kS97AQg'
+---
diff --git a/src/content/videos/aindustriosa/dntvdxvmlqy.md b/src/content/videos/aindustriosa/dntvdxvmlqy.md
new file mode 100644
index 00000000..5a07dc28
--- /dev/null
+++ b/src/content/videos/aindustriosa/dntvdxvmlqy.md
@@ -0,0 +1,11 @@
+---
+sourceId: 'DnTVDXVMLqY'
+groupId: 'aindustriosa'
+groupName: 'A Industriosa'
+groupLogo: 'https://vigotech.org/images/aindustriosa.png'
+title: '20250322 - Galegos na FOSDEM - Sam Thursfield'
+player: 'youtube'
+url: 'https://www.youtube.com/watch?v=DnTVDXVMLqY'
+publishedAt: 1743145954000
+thumbnail: 'https://i.ytimg.com/vi/DnTVDXVMLqY/hqdefault.jpg'
+---
diff --git a/src/content/videos/aindustriosa/e-3kozcmwbu.md b/src/content/videos/aindustriosa/e-3kozcmwbu.md
new file mode 100644
index 00000000..8b73aaf3
--- /dev/null
+++ b/src/content/videos/aindustriosa/e-3kozcmwbu.md
@@ -0,0 +1,11 @@
+---
+sourceId: 'E-3KOZCmwBU'
+groupId: 'aindustriosa'
+groupName: 'A Industriosa'
+groupLogo: 'https://vigotech.org/images/aindustriosa.png'
+title: '20230511 - Engineering Manager: Beyond Leadership'
+player: 'youtube'
+url: 'https://www.youtube.com/watch?v=E-3KOZCmwBU'
+publishedAt: 1683929679000
+thumbnail: 'https://i.ytimg.com/vi/E-3KOZCmwBU/hqdefault.jpg'
+---
diff --git a/src/content/videos/aindustriosa/e0sgibol7ek.md b/src/content/videos/aindustriosa/e0sgibol7ek.md
new file mode 100644
index 00000000..d0339c88
--- /dev/null
+++ b/src/content/videos/aindustriosa/e0sgibol7ek.md
@@ -0,0 +1,11 @@
+---
+sourceId: 'E0sGiBOL7ek'
+groupId: 'aindustriosa'
+groupName: 'A Industriosa'
+groupLogo: 'https://vigotech.org/images/aindustriosa.png'
+title: '20190304 - Charla Íñigo Echenique - Diseño Naval - TS Royalist'
+player: 'youtube'
+url: 'https://www.youtube.com/watch?v=E0sGiBOL7ek'
+publishedAt: null
+thumbnail: 'https://i.ytimg.com/vi/E0sGiBOL7ek/hqdefault.jpg?sqp=-oaymwEcCNACELwBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==&rs=AOn4CLBzjgkLhY-knpe5xe9uafFP7XAmPg'
+---
diff --git a/src/content/videos/aindustriosa/eply147xqzw.md b/src/content/videos/aindustriosa/eply147xqzw.md
new file mode 100644
index 00000000..9cada929
--- /dev/null
+++ b/src/content/videos/aindustriosa/eply147xqzw.md
@@ -0,0 +1,11 @@
+---
+sourceId: 'Eply147XQZw'
+groupId: 'aindustriosa'
+groupName: 'A Industriosa'
+groupLogo: 'https://vigotech.org/images/aindustriosa.png'
+title: '20180309 - Robótica de competición (Carreras, mini-sumo y humanoides) - OPROBOTS'
+player: 'youtube'
+url: 'https://www.youtube.com/watch?v=Eply147XQZw'
+publishedAt: null
+thumbnail: 'https://i.ytimg.com/vi/Eply147XQZw/hqdefault.jpg?sqp=-oaymwEcCNACELwBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==&rs=AOn4CLDCa_jcmm2jmBnG61pts0Avy1lECQ'
+---
diff --git a/src/content/videos/aindustriosa/fckzbnkm1hu.md b/src/content/videos/aindustriosa/fckzbnkm1hu.md
new file mode 100644
index 00000000..c6f150a5
--- /dev/null
+++ b/src/content/videos/aindustriosa/fckzbnkm1hu.md
@@ -0,0 +1,11 @@
+---
+sourceId: 'FckZbnkM1hU'
+groupId: 'aindustriosa'
+groupName: 'A Industriosa'
+groupLogo: 'https://vigotech.org/images/aindustriosa.png'
+title: 'Regata Solar - [LIVE] - Curso Electrónica e propulsión'
+player: 'youtube'
+url: 'https://www.youtube.com/watch?v=FckZbnkM1hU'
+publishedAt: null
+thumbnail: 'https://i.ytimg.com/vi/FckZbnkM1hU/hqdefault.jpg?sqp=-oaymwEcCNACELwBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==&rs=AOn4CLDLNvoQ9CYnmpw4NaUhFSq7LDP2Pg'
+---
diff --git a/src/content/videos/aindustriosa/fuq5glfzmja.md b/src/content/videos/aindustriosa/fuq5glfzmja.md
new file mode 100644
index 00000000..0b603854
--- /dev/null
+++ b/src/content/videos/aindustriosa/fuq5glfzmja.md
@@ -0,0 +1,11 @@
+---
+sourceId: 'FuQ5glFzmJA'
+groupId: 'aindustriosa'
+groupName: 'A Industriosa'
+groupLogo: 'https://vigotech.org/images/aindustriosa.png'
+title: '20200408 - [LIVE] - Regata Solar - Curso Radiocontrol e Telemetría'
+player: 'youtube'
+url: 'https://www.youtube.com/watch?v=FuQ5glFzmJA'
+publishedAt: null
+thumbnail: 'https://i.ytimg.com/vi/FuQ5glFzmJA/hqdefault.jpg?sqp=-oaymwEcCNACELwBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==&rs=AOn4CLCG2hFvzBi8NYgv9x3GOHZR4gm8Bg'
+---
diff --git a/src/content/videos/aindustriosa/gtqkbhfsr-g.md b/src/content/videos/aindustriosa/gtqkbhfsr-g.md
new file mode 100644
index 00000000..e6fcfc8f
--- /dev/null
+++ b/src/content/videos/aindustriosa/gtqkbhfsr-g.md
@@ -0,0 +1,11 @@
+---
+sourceId: 'GtqKbhFsR_g'
+groupId: 'aindustriosa'
+groupName: 'A Industriosa'
+groupLogo: 'https://vigotech.org/images/aindustriosa.png'
+title: '20200406 - Regata Solar - Curso Electrónica e propulsión'
+player: 'youtube'
+url: 'https://www.youtube.com/watch?v=GtqKbhFsR_g'
+publishedAt: null
+thumbnail: 'https://i.ytimg.com/vi/GtqKbhFsR_g/hqdefault.jpg?sqp=-oaymwEcCNACELwBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==&rs=AOn4CLBzvo_9B22hlAxtsqoIDcqzcfM79g'
+---
diff --git a/src/content/videos/aindustriosa/jgk0obo0a7e.md b/src/content/videos/aindustriosa/jgk0obo0a7e.md
new file mode 100644
index 00000000..08cb92ff
--- /dev/null
+++ b/src/content/videos/aindustriosa/jgk0obo0a7e.md
@@ -0,0 +1,11 @@
+---
+sourceId: 'JgK0oBo0a7E'
+groupId: 'aindustriosa'
+groupName: 'A Industriosa'
+groupLogo: 'https://vigotech.org/images/aindustriosa.png'
+title: '20220709 - Autoconsumo Solar'
+player: 'youtube'
+url: 'https://www.youtube.com/watch?v=JgK0oBo0a7E'
+publishedAt: 1657412138000
+thumbnail: 'https://i.ytimg.com/vi/JgK0oBo0a7E/hqdefault.jpg'
+---
diff --git a/src/content/videos/aindustriosa/kx2p4b1cxck.md b/src/content/videos/aindustriosa/kx2p4b1cxck.md
new file mode 100644
index 00000000..194bd42b
--- /dev/null
+++ b/src/content/videos/aindustriosa/kx2p4b1cxck.md
@@ -0,0 +1,11 @@
+---
+sourceId: 'Kx2P4b1cxCk'
+groupId: 'aindustriosa'
+groupName: 'A Industriosa'
+groupLogo: 'https://vigotech.org/images/aindustriosa.png'
+title: '20180301 - Monitorización de una regata de barcos radiocontrol'
+player: 'youtube'
+url: 'https://www.youtube.com/watch?v=Kx2P4b1cxCk'
+publishedAt: null
+thumbnail: 'https://i.ytimg.com/vi/Kx2P4b1cxCk/hqdefault.jpg?sqp=-oaymwEcCNACELwBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==&rs=AOn4CLAQtgx6tz6CsJVjnF6C-PxC9jlsBg'
+---
diff --git a/src/content/videos/aindustriosa/lo6yuysnamu.md b/src/content/videos/aindustriosa/lo6yuysnamu.md
new file mode 100644
index 00000000..27f345be
--- /dev/null
+++ b/src/content/videos/aindustriosa/lo6yuysnamu.md
@@ -0,0 +1,11 @@
+---
+sourceId: 'lo6yuYSnAMU'
+groupId: 'aindustriosa'
+groupName: 'A Industriosa'
+groupLogo: 'https://vigotech.org/images/aindustriosa.png'
+title: '20190320 - Introducción a las FPGAs+Verilog'
+player: 'youtube'
+url: 'https://www.youtube.com/watch?v=lo6yuYSnAMU'
+publishedAt: null
+thumbnail: 'https://i.ytimg.com/vi/lo6yuYSnAMU/hqdefault.jpg?sqp=-oaymwEcCNACELwBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==&rs=AOn4CLCSJH9jTIVlx7IrSeD6Y6rvrysnJw'
+---
diff --git a/src/content/videos/aindustriosa/m9beeq0osq8.md b/src/content/videos/aindustriosa/m9beeq0osq8.md
new file mode 100644
index 00000000..9b57de64
--- /dev/null
+++ b/src/content/videos/aindustriosa/m9beeq0osq8.md
@@ -0,0 +1,11 @@
+---
+sourceId: 'M9BeEq0OSq8'
+groupId: 'aindustriosa'
+groupName: 'A Industriosa'
+groupLogo: 'https://vigotech.org/images/aindustriosa.png'
+title: 'VigoTech na TVG'
+player: 'youtube'
+url: 'https://www.youtube.com/watch?v=M9BeEq0OSq8'
+publishedAt: null
+thumbnail: 'https://i.ytimg.com/vi/M9BeEq0OSq8/hqdefault.jpg?sqp=-oaymwEcCNACELwBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==&rs=AOn4CLAsgj-FgwowiXpt-YqKbpyktVNTcg'
+---
diff --git a/src/content/videos/aindustriosa/nf8a-orqssi.md b/src/content/videos/aindustriosa/nf8a-orqssi.md
new file mode 100644
index 00000000..cede8724
--- /dev/null
+++ b/src/content/videos/aindustriosa/nf8a-orqssi.md
@@ -0,0 +1,11 @@
+---
+sourceId: 'nf8a_OrQSSI'
+groupId: 'aindustriosa'
+groupName: 'A Industriosa'
+groupLogo: 'https://vigotech.org/images/aindustriosa.png'
+title: 'Badge OSHWDem 2017'
+player: 'youtube'
+url: 'https://www.youtube.com/watch?v=nf8a_OrQSSI'
+publishedAt: null
+thumbnail: 'https://i.ytimg.com/vi/nf8a_OrQSSI/hqdefault.jpg?sqp=-oaymwEcCNACELwBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==&rs=AOn4CLBXxCQYyYkvBXdE3MKL0U1HjYn12g'
+---
diff --git a/src/content/videos/aindustriosa/nkcyw4gnrmg.md b/src/content/videos/aindustriosa/nkcyw4gnrmg.md
new file mode 100644
index 00000000..5b22905b
--- /dev/null
+++ b/src/content/videos/aindustriosa/nkcyw4gnrmg.md
@@ -0,0 +1,11 @@
+---
+sourceId: 'nkcYW4GnRmg'
+groupId: 'aindustriosa'
+groupName: 'A Industriosa'
+groupLogo: 'https://vigotech.org/images/aindustriosa.png'
+title: '20220924 - Como (no) fabricar Motores Eléctricos'
+player: 'youtube'
+url: 'https://www.youtube.com/watch?v=nkcYW4GnRmg'
+publishedAt: 1664205122000
+thumbnail: 'https://i.ytimg.com/vi/nkcYW4GnRmg/hqdefault.jpg'
+---
diff --git a/src/content/videos/aindustriosa/nkeztnat9g4.md b/src/content/videos/aindustriosa/nkeztnat9g4.md
new file mode 100644
index 00000000..5081ba01
--- /dev/null
+++ b/src/content/videos/aindustriosa/nkeztnat9g4.md
@@ -0,0 +1,11 @@
+---
+sourceId: 'nkEzTnaT9g4'
+groupId: 'aindustriosa'
+groupName: 'A Industriosa'
+groupLogo: 'https://vigotech.org/images/aindustriosa.png'
+title: '20230626 - Robótica de competición: OPRobots, moita, moita proba e erro'
+player: 'youtube'
+url: 'https://www.youtube.com/watch?v=nkEzTnaT9g4'
+publishedAt: 1688074416000
+thumbnail: 'https://i.ytimg.com/vi/nkEzTnaT9g4/hqdefault.jpg'
+---
diff --git a/src/content/videos/aindustriosa/ojfntjlmroo.md b/src/content/videos/aindustriosa/ojfntjlmroo.md
new file mode 100644
index 00000000..8f576f2e
--- /dev/null
+++ b/src/content/videos/aindustriosa/ojfntjlmroo.md
@@ -0,0 +1,11 @@
+---
+sourceId: 'OJFnTJlMrOo'
+groupId: 'aindustriosa'
+groupName: 'A Industriosa'
+groupLogo: 'https://vigotech.org/images/aindustriosa.png'
+title: 'Galicia, el espacio y por qué seguir explorando'
+player: 'youtube'
+url: 'https://www.youtube.com/watch?v=OJFnTJlMrOo'
+publishedAt: null
+thumbnail: 'https://i.ytimg.com/vi/OJFnTJlMrOo/hqdefault.jpg?sqp=-oaymwEcCNACELwBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==&rs=AOn4CLA8vKHsX1V8S9ts-oZ1NzeREZ49EQ'
+---
diff --git a/src/content/videos/aindustriosa/ozy-ptjtpxu.md b/src/content/videos/aindustriosa/ozy-ptjtpxu.md
new file mode 100644
index 00000000..24687c3c
--- /dev/null
+++ b/src/content/videos/aindustriosa/ozy-ptjtpxu.md
@@ -0,0 +1,11 @@
+---
+sourceId: 'Ozy-ptJtpXU'
+groupId: 'aindustriosa'
+groupName: 'A Industriosa'
+groupLogo: 'https://vigotech.org/images/aindustriosa.png'
+title: '20230624 - Tecnoloxía Aplicada á Investigación en Ocupación, Igualdade e Saúde'
+player: 'youtube'
+url: 'https://www.youtube.com/watch?v=Ozy-ptJtpXU'
+publishedAt: 1688114733000
+thumbnail: 'https://i.ytimg.com/vi/Ozy-ptJtpXU/hqdefault.jpg'
+---
diff --git a/src/content/videos/aindustriosa/p4jz9ramhse.md b/src/content/videos/aindustriosa/p4jz9ramhse.md
new file mode 100644
index 00000000..4d20e6a0
--- /dev/null
+++ b/src/content/videos/aindustriosa/p4jz9ramhse.md
@@ -0,0 +1,11 @@
+---
+sourceId: 'P4Jz9ramhsE'
+groupId: 'aindustriosa'
+groupName: 'A Industriosa'
+groupLogo: 'https://vigotech.org/images/aindustriosa.png'
+title: 'Introducción a Mesa, por Igalia 28/10/2023'
+player: 'youtube'
+url: 'https://www.youtube.com/watch?v=P4Jz9ramhsE'
+publishedAt: 1698684367000
+thumbnail: 'https://i.ytimg.com/vi/P4Jz9ramhsE/hqdefault.jpg'
+---
diff --git a/src/content/videos/aindustriosa/pj5mekki06g.md b/src/content/videos/aindustriosa/pj5mekki06g.md
new file mode 100644
index 00000000..0945c8e6
--- /dev/null
+++ b/src/content/videos/aindustriosa/pj5mekki06g.md
@@ -0,0 +1,11 @@
+---
+sourceId: 'PJ5mEkki06g'
+groupId: 'aindustriosa'
+groupName: 'A Industriosa'
+groupLogo: 'https://vigotech.org/images/aindustriosa.png'
+title: '20240313 - Solana: unha guía para principiantes, por José Corral'
+player: 'youtube'
+url: 'https://www.youtube.com/watch?v=PJ5mEkki06g'
+publishedAt: 1718384640000
+thumbnail: 'https://i.ytimg.com/vi/PJ5mEkki06g/hqdefault.jpg'
+---
diff --git a/src/content/videos/aindustriosa/r-k0saprzpw.md b/src/content/videos/aindustriosa/r-k0saprzpw.md
new file mode 100644
index 00000000..cfa44468
--- /dev/null
+++ b/src/content/videos/aindustriosa/r-k0saprzpw.md
@@ -0,0 +1,11 @@
+---
+sourceId: 'R_K0saprZPw'
+groupId: 'aindustriosa'
+groupName: 'A Industriosa'
+groupLogo: 'https://vigotech.org/images/aindustriosa.png'
+title: 'Reciclaxe de plásticos a pequeña escala con máquinas open source'
+player: 'youtube'
+url: 'https://www.youtube.com/watch?v=R_K0saprZPw'
+publishedAt: null
+thumbnail: 'https://i.ytimg.com/vi/R_K0saprZPw/hqdefault.jpg?sqp=-oaymwEcCNACELwBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==&rs=AOn4CLB4uKPyOSAoKPrr42UhUaR_6iZ6WA'
+---
diff --git a/src/content/videos/aindustriosa/r1czgu-swsa.md b/src/content/videos/aindustriosa/r1czgu-swsa.md
new file mode 100644
index 00000000..23e8eb56
--- /dev/null
+++ b/src/content/videos/aindustriosa/r1czgu-swsa.md
@@ -0,0 +1,11 @@
+---
+sourceId: 'R1CZGU-SWsA'
+groupId: 'aindustriosa'
+groupName: 'A Industriosa'
+groupLogo: 'https://vigotech.org/images/aindustriosa.png'
+title: '20180216 - Bulebule - Making of de un robot "micromouse"'
+player: 'youtube'
+url: 'https://www.youtube.com/watch?v=R1CZGU-SWsA'
+publishedAt: null
+thumbnail: 'https://i.ytimg.com/vi/R1CZGU-SWsA/hqdefault.jpg?sqp=-oaymwE2CNACELwBSFXyq4qpAygIARUAAIhCGAFwAcABBvABAfgB_gmAAtAFigIMCAAQARhmIGYoZjAP&rs=AOn4CLAeH7osLarFdp6JB7EgHTQxwloL9g'
+---
diff --git a/src/content/videos/aindustriosa/rezbm9lhdh4.md b/src/content/videos/aindustriosa/rezbm9lhdh4.md
new file mode 100644
index 00000000..72fae3d4
--- /dev/null
+++ b/src/content/videos/aindustriosa/rezbm9lhdh4.md
@@ -0,0 +1,11 @@
+---
+sourceId: 'ReZbM9lhdH4'
+groupId: 'aindustriosa'
+groupName: 'A Industriosa'
+groupLogo: 'https://vigotech.org/images/aindustriosa.png'
+title: '20180314 - Introducción al diseño naval - III Regata Solar - Íñigo Echenique'
+player: 'youtube'
+url: 'https://www.youtube.com/watch?v=ReZbM9lhdH4'
+publishedAt: null
+thumbnail: 'https://i.ytimg.com/vi/ReZbM9lhdH4/hqdefault.jpg?sqp=-oaymwEcCNACELwBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==&rs=AOn4CLAreF2SzojhDu32tSX4n_5jruApmg'
+---
diff --git a/src/content/videos/aindustriosa/rmtwdpjaheu.md b/src/content/videos/aindustriosa/rmtwdpjaheu.md
new file mode 100644
index 00000000..7cbde0b9
--- /dev/null
+++ b/src/content/videos/aindustriosa/rmtwdpjaheu.md
@@ -0,0 +1,11 @@
+---
+sourceId: 'RMtWdPJaHeU'
+groupId: 'aindustriosa'
+groupName: 'A Industriosa'
+groupLogo: 'https://vigotech.org/images/aindustriosa.png'
+title: '20250322 - Galegos na FOSDEM - Xabier Crespo'
+player: 'youtube'
+url: 'https://www.youtube.com/watch?v=RMtWdPJaHeU'
+publishedAt: 1743145983000
+thumbnail: 'https://i.ytimg.com/vi/RMtWdPJaHeU/hqdefault.jpg'
+---
diff --git a/src/content/videos/aindustriosa/stf14pwimp4.md b/src/content/videos/aindustriosa/stf14pwimp4.md
new file mode 100644
index 00000000..6952568a
--- /dev/null
+++ b/src/content/videos/aindustriosa/stf14pwimp4.md
@@ -0,0 +1,11 @@
+---
+sourceId: 'STF14PwIMP4'
+groupId: 'aindustriosa'
+groupName: 'A Industriosa'
+groupLogo: 'https://vigotech.org/images/aindustriosa.png'
+title: 'CES UVigo: Fabricación de barcos solares tripulados para competición'
+player: 'youtube'
+url: 'https://www.youtube.com/watch?v=STF14PwIMP4'
+publishedAt: 1648707933000
+thumbnail: 'https://i.ytimg.com/vi/STF14PwIMP4/hqdefault.jpg'
+---
diff --git a/src/content/videos/aindustriosa/tnmsrnwnpyw.md b/src/content/videos/aindustriosa/tnmsrnwnpyw.md
new file mode 100644
index 00000000..ee90bb37
--- /dev/null
+++ b/src/content/videos/aindustriosa/tnmsrnwnpyw.md
@@ -0,0 +1,11 @@
+---
+sourceId: 'tNMsRnwnpYw'
+groupId: 'aindustriosa'
+groupName: 'A Industriosa'
+groupLogo: 'https://vigotech.org/images/aindustriosa.png'
+title: '20200424 - [LIVE] - Open Research Rocketry'
+player: 'youtube'
+url: 'https://www.youtube.com/watch?v=tNMsRnwnpYw'
+publishedAt: null
+thumbnail: 'https://i.ytimg.com/vi/tNMsRnwnpYw/hqdefault.jpg?sqp=-oaymwEcCNACELwBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==&rs=AOn4CLDRgqTJadY_1yBdDFHx-Bt0pEfvBg'
+---
diff --git a/src/content/videos/aindustriosa/up-hukomzco.md b/src/content/videos/aindustriosa/up-hukomzco.md
new file mode 100644
index 00000000..a4d7d39f
--- /dev/null
+++ b/src/content/videos/aindustriosa/up-hukomzco.md
@@ -0,0 +1,11 @@
+---
+sourceId: 'UP_HuKoMZco'
+groupId: 'aindustriosa'
+groupName: 'A Industriosa'
+groupLogo: 'https://vigotech.org/images/aindustriosa.png'
+title: '20181213 - E-téxtiles nos espacios maker'
+player: 'youtube'
+url: 'https://www.youtube.com/watch?v=UP_HuKoMZco'
+publishedAt: null
+thumbnail: 'https://i.ytimg.com/vi/UP_HuKoMZco/hqdefault.jpg?sqp=-oaymwEcCNACELwBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==&rs=AOn4CLDsGOcV47e17Rd5dn0gG07Eez48Ag'
+---
diff --git a/src/content/videos/aindustriosa/vrgi0hr0dsk.md b/src/content/videos/aindustriosa/vrgi0hr0dsk.md
new file mode 100644
index 00000000..bee26b24
--- /dev/null
+++ b/src/content/videos/aindustriosa/vrgi0hr0dsk.md
@@ -0,0 +1,11 @@
+---
+sourceId: 'Vrgi0hr0Dsk'
+groupId: 'aindustriosa'
+groupName: 'A Industriosa'
+groupLogo: 'https://vigotech.org/images/aindustriosa.png'
+title: '20190325 - Consecuencias de la Nueva Directiva de Copyright Europea (y qué puedo hacer)'
+player: 'youtube'
+url: 'https://www.youtube.com/watch?v=Vrgi0hr0Dsk'
+publishedAt: null
+thumbnail: 'https://i.ytimg.com/vi/Vrgi0hr0Dsk/hqdefault.jpg?sqp=-oaymwEcCNACELwBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==&rs=AOn4CLB91tZI_67qLs8wQK7vIUlFhmgNgA'
+---
diff --git a/src/content/videos/aindustriosa/vyni1x3qgi0.md b/src/content/videos/aindustriosa/vyni1x3qgi0.md
new file mode 100644
index 00000000..a85fd70d
--- /dev/null
+++ b/src/content/videos/aindustriosa/vyni1x3qgi0.md
@@ -0,0 +1,11 @@
+---
+sourceId: 'VynI1x3QGI0'
+groupId: 'aindustriosa'
+groupName: 'A Industriosa'
+groupLogo: 'https://vigotech.org/images/aindustriosa.png'
+title: '20200319 - [LIVE] - Introducción a Lora e LoraWAN'
+player: 'youtube'
+url: 'https://www.youtube.com/watch?v=VynI1x3QGI0'
+publishedAt: null
+thumbnail: 'https://i.ytimg.com/vi/VynI1x3QGI0/hqdefault.jpg?sqp=-oaymwEcCNACELwBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==&rs=AOn4CLAH7AHrp7Z9ColRWV4U1GIlynOtlw'
+---
diff --git a/src/content/videos/aindustriosa/w3binwrun88.md b/src/content/videos/aindustriosa/w3binwrun88.md
new file mode 100644
index 00000000..7ff24425
--- /dev/null
+++ b/src/content/videos/aindustriosa/w3binwrun88.md
@@ -0,0 +1,11 @@
+---
+sourceId: 'w3BInWruN88'
+groupId: 'aindustriosa'
+groupName: 'A Industriosa'
+groupLogo: 'https://vigotech.org/images/aindustriosa.png'
+title: 'Time-lapse da montaxe Scanner 3D Ciclop'
+player: 'youtube'
+url: 'https://www.youtube.com/watch?v=w3BInWruN88'
+publishedAt: null
+thumbnail: 'https://i.ytimg.com/vi/w3BInWruN88/hqdefault.jpg?sqp=-oaymwEcCNACELwBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==&rs=AOn4CLAB0N6hiOIdOMk4JfQlRsZWy8SC-A'
+---
diff --git a/src/content/videos/aindustriosa/w40f9woatq4.md b/src/content/videos/aindustriosa/w40f9woatq4.md
new file mode 100644
index 00000000..3e06d156
--- /dev/null
+++ b/src/content/videos/aindustriosa/w40f9woatq4.md
@@ -0,0 +1,11 @@
+---
+sourceId: 'w40F9WOatq4'
+groupId: 'aindustriosa'
+groupName: 'A Industriosa'
+groupLogo: 'https://vigotech.org/images/aindustriosa.png'
+title: '20240613 - Descobre o poder da programación funcional a través de OCaml, por Jose Castillo'
+player: 'youtube'
+url: 'https://www.youtube.com/watch?v=w40F9WOatq4'
+publishedAt: 1718381629000
+thumbnail: 'https://i.ytimg.com/vi/w40F9WOatq4/hqdefault.jpg'
+---
diff --git a/src/content/videos/aindustriosa/ygde-hwi2-m.md b/src/content/videos/aindustriosa/ygde-hwi2-m.md
new file mode 100644
index 00000000..8be7b9da
--- /dev/null
+++ b/src/content/videos/aindustriosa/ygde-hwi2-m.md
@@ -0,0 +1,11 @@
+---
+sourceId: 'ygDE-hWi2-M'
+groupId: 'aindustriosa'
+groupName: 'A Industriosa'
+groupLogo: 'https://vigotech.org/images/aindustriosa.png'
+title: '20180123 - TVG - Entrevista a Ana Cidre'
+player: 'youtube'
+url: 'https://www.youtube.com/watch?v=ygDE-hWi2-M'
+publishedAt: null
+thumbnail: 'https://i.ytimg.com/vi/ygDE-hWi2-M/hqdefault.jpg?sqp=-oaymwEcCNACELwBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==&rs=AOn4CLD9draHZNYFlEJ2WeS7Cdt-d9TrqQ'
+---
diff --git a/src/content/videos/aindustriosa/z1q7z6whz8a.md b/src/content/videos/aindustriosa/z1q7z6whz8a.md
new file mode 100644
index 00000000..75fb9a02
--- /dev/null
+++ b/src/content/videos/aindustriosa/z1q7z6whz8a.md
@@ -0,0 +1,11 @@
+---
+sourceId: 'Z1Q7z6Whz8A'
+groupId: 'aindustriosa'
+groupName: 'A Industriosa'
+groupLogo: 'https://vigotech.org/images/aindustriosa.png'
+title: '20250322 - Galegos na FOSDEM - Santiago Saavedra'
+player: 'youtube'
+url: 'https://www.youtube.com/watch?v=Z1Q7z6Whz8A'
+publishedAt: 1743145846000
+thumbnail: 'https://i.ytimg.com/vi/Z1Q7z6Whz8A/hqdefault.jpg'
+---
diff --git a/src/content/videos/gdgvigo/85v3pl50yl4.md b/src/content/videos/gdgvigo/85v3pl50yl4.md
new file mode 100644
index 00000000..fa58c24f
--- /dev/null
+++ b/src/content/videos/gdgvigo/85v3pl50yl4.md
@@ -0,0 +1,11 @@
+---
+sourceId: '85V3Pl50Yl4'
+groupId: 'gdgvigo'
+groupName: 'GDG Vigo'
+groupLogo: 'https://vigotech.org/images/gdg_vigo.png'
+title: 'GDG Vigo - Web Components y Polymer'
+player: 'youtube'
+url: 'https://www.youtube.com/watch?v=85V3Pl50Yl4'
+publishedAt: 1441652288000
+thumbnail: 'https://i.ytimg.com/vi/85V3Pl50Yl4/hqdefault.jpg'
+---
diff --git a/src/content/videos/gdgvigo/rlcej7ob2yq.md b/src/content/videos/gdgvigo/rlcej7ob2yq.md
new file mode 100644
index 00000000..419561b2
--- /dev/null
+++ b/src/content/videos/gdgvigo/rlcej7ob2yq.md
@@ -0,0 +1,11 @@
+---
+sourceId: 'RLceJ7Ob2yQ'
+groupId: 'gdgvigo'
+groupName: 'GDG Vigo'
+groupLogo: 'https://vigotech.org/images/gdg_vigo.png'
+title: 'Floppy disks By Breogan and Alberto'
+player: 'youtube'
+url: 'https://www.youtube.com/watch?v=RLceJ7Ob2yQ'
+publishedAt: 1401118959000
+thumbnail: 'https://i.ytimg.com/vi/RLceJ7Ob2yQ/hqdefault.jpg'
+---
diff --git a/src/content/videos/gdgvigo/u4kykubpg6c.md b/src/content/videos/gdgvigo/u4kykubpg6c.md
new file mode 100644
index 00000000..ef2c30ac
--- /dev/null
+++ b/src/content/videos/gdgvigo/u4kykubpg6c.md
@@ -0,0 +1,11 @@
+---
+sourceId: 'u4KYKUbpg6c'
+groupId: 'gdgvigo'
+groupName: 'GDG Vigo'
+groupLogo: 'https://vigotech.org/images/gdg_vigo.png'
+title: 'GDG Vigo - Python y Django'
+player: 'youtube'
+url: 'https://www.youtube.com/watch?v=u4KYKUbpg6c'
+publishedAt: 1441650886000
+thumbnail: 'https://i.ytimg.com/vi/u4KYKUbpg6c/hqdefault.jpg'
+---
diff --git a/src/content/videos/phpvigo/2cx3zyjthmm.md b/src/content/videos/phpvigo/2cx3zyjthmm.md
new file mode 100644
index 00000000..4549c0cf
--- /dev/null
+++ b/src/content/videos/phpvigo/2cx3zyjthmm.md
@@ -0,0 +1,11 @@
+---
+sourceId: '2cx3ZyJTHmM'
+groupId: 'phpvigo'
+groupName: 'PHPVigo'
+groupLogo: 'https://vigotech.org/images/php_vigo.jpg'
+title: 'Charla sobre GIT por Jesus Amieiro en #PHPVigo Meetup #2'
+player: 'youtube'
+url: 'https://www.youtube.com/watch?v=2cx3ZyJTHmM'
+publishedAt: null
+thumbnail: 'https://i.ytimg.com/vi/2cx3ZyJTHmM/hqdefault.jpg?sqp=-oaymwE2CNACELwBSFXyq4qpAygIARUAAIhCGAFwAcABBvABAfgB_gmAAtAFigIMCAAQARhyIFMoKjAP&rs=AOn4CLAlX5XFtE1w1nIa8FXfIipncqYszQ'
+---
diff --git a/src/content/videos/phpvigo/304ikjdidg8.md b/src/content/videos/phpvigo/304ikjdidg8.md
new file mode 100644
index 00000000..dc7400b3
--- /dev/null
+++ b/src/content/videos/phpvigo/304ikjdidg8.md
@@ -0,0 +1,11 @@
+---
+sourceId: '304IKjdiDG8'
+groupId: 'phpvigo'
+groupName: 'PHPVigo'
+groupLogo: 'https://vigotech.org/images/php_vigo.jpg'
+title: 'Zend Certified Engineer (Orestes Carracedo)'
+player: 'youtube'
+url: 'https://www.youtube.com/watch?v=304IKjdiDG8'
+publishedAt: null
+thumbnail: 'https://i.ytimg.com/vi/304IKjdiDG8/hqdefault.jpg?sqp=-oaymwEcCNACELwBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==&rs=AOn4CLDJiDt-L2tzofwB7f9gMR76aLW02Q'
+---
diff --git a/src/content/videos/phpvigo/3n3ak0dyjq4.md b/src/content/videos/phpvigo/3n3ak0dyjq4.md
new file mode 100644
index 00000000..d4cb05da
--- /dev/null
+++ b/src/content/videos/phpvigo/3n3ak0dyjq4.md
@@ -0,0 +1,11 @@
+---
+sourceId: '3n3aK0DYJq4'
+groupId: 'phpvigo'
+groupName: 'PHPVigo'
+groupLogo: 'https://vigotech.org/images/php_vigo.jpg'
+title: 'Novedades PHP 7.2 con Raúl Araya'
+player: 'youtube'
+url: 'https://www.youtube.com/watch?v=3n3aK0DYJq4'
+publishedAt: 1517558746000
+thumbnail: 'https://i.ytimg.com/vi/3n3aK0DYJq4/hqdefault.jpg'
+---
diff --git a/src/content/videos/phpvigo/3wsdxmk9miw.md b/src/content/videos/phpvigo/3wsdxmk9miw.md
new file mode 100644
index 00000000..62b4ef15
--- /dev/null
+++ b/src/content/videos/phpvigo/3wsdxmk9miw.md
@@ -0,0 +1,11 @@
+---
+sourceId: '3WSDxMK9MIw'
+groupId: 'phpvigo'
+groupName: 'PHPVigo'
+groupLogo: 'https://vigotech.org/images/php_vigo.jpg'
+title: 'PHPVigo #40: New no, lo siguiente. Patrones de creación de objetos 🔊 Fran Iglesias'
+player: 'youtube'
+url: 'https://www.youtube.com/watch?v=3WSDxMK9MIw'
+publishedAt: 1604480727000
+thumbnail: 'https://i.ytimg.com/vi/3WSDxMK9MIw/hqdefault.jpg'
+---
diff --git a/src/content/videos/phpvigo/4hsgawqb20g.md b/src/content/videos/phpvigo/4hsgawqb20g.md
new file mode 100644
index 00000000..c9cee763
--- /dev/null
+++ b/src/content/videos/phpvigo/4hsgawqb20g.md
@@ -0,0 +1,11 @@
+---
+sourceId: '4HsGaWqB20g'
+groupId: 'phpvigo'
+groupName: 'PHPVigo'
+groupLogo: 'https://vigotech.org/images/php_vigo.jpg'
+title: '2017 04 26 21 44 12'
+player: 'youtube'
+url: 'https://www.youtube.com/watch?v=4HsGaWqB20g'
+publishedAt: null
+thumbnail: 'https://i.ytimg.com/vi/4HsGaWqB20g/hqdefault.jpg?sqp=-oaymwEcCNACELwBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==&rs=AOn4CLBFDJQzDFEnogWp7Scm5-v1-c0lDQ'
+---
diff --git a/src/content/videos/phpvigo/7eq6wcsi6ik.md b/src/content/videos/phpvigo/7eq6wcsi6ik.md
new file mode 100644
index 00000000..5ef204b0
--- /dev/null
+++ b/src/content/videos/phpvigo/7eq6wcsi6ik.md
@@ -0,0 +1,11 @@
+---
+sourceId: '7eQ6WCsi6ik'
+groupId: 'phpvigo'
+groupName: 'PHPVigo'
+groupLogo: 'https://vigotech.org/images/php_vigo.jpg'
+title: 'Charla presentación PHPVigo #PHPVigo Meetup#1'
+player: 'youtube'
+url: 'https://www.youtube.com/watch?v=7eQ6WCsi6ik'
+publishedAt: null
+thumbnail: 'https://i.ytimg.com/vi/7eQ6WCsi6ik/hqdefault.jpg?sqp=-oaymwEcCNACELwBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==&rs=AOn4CLC5HpaFD5PmWYegUZRb39Bq8Q4AiA'
+---
diff --git a/src/content/videos/phpvigo/8mrfrbyffpm.md b/src/content/videos/phpvigo/8mrfrbyffpm.md
new file mode 100644
index 00000000..e4d60fde
--- /dev/null
+++ b/src/content/videos/phpvigo/8mrfrbyffpm.md
@@ -0,0 +1,11 @@
+---
+sourceId: '8mRFrByfFpM'
+groupId: 'phpvigo'
+groupName: 'PHPVigo'
+groupLogo: 'https://vigotech.org/images/php_vigo.jpg'
+title: 'Double Extension Attack (@sergiocarracedo)'
+player: 'youtube'
+url: 'https://www.youtube.com/watch?v=8mRFrByfFpM'
+publishedAt: 1507017150000
+thumbnail: 'https://i.ytimg.com/vi/8mRFrByfFpM/hqdefault.jpg'
+---
diff --git a/src/content/videos/phpvigo/bteb03r2hpo.md b/src/content/videos/phpvigo/bteb03r2hpo.md
new file mode 100644
index 00000000..117497ed
--- /dev/null
+++ b/src/content/videos/phpvigo/bteb03r2hpo.md
@@ -0,0 +1,11 @@
+---
+sourceId: 'bteb03R2hpo'
+groupId: 'phpvigo'
+groupName: 'PHPVigo'
+groupLogo: 'https://vigotech.org/images/php_vigo.jpg'
+title: 'Dónde está mi ñ" -Miguel Gonzalez (@migonzalvar)'
+player: 'youtube'
+url: 'https://www.youtube.com/watch?v=bteb03R2hpo'
+publishedAt: null
+thumbnail: 'https://i.ytimg.com/vi/bteb03R2hpo/hqdefault.jpg?sqp=-oaymwEcCNACELwBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==&rs=AOn4CLAEhHaRceJ0ItLulnYYNkFNf9KAAA'
+---
diff --git a/src/content/videos/phpvigo/cb3fhly1sc4.md b/src/content/videos/phpvigo/cb3fhly1sc4.md
new file mode 100644
index 00000000..1460fe82
--- /dev/null
+++ b/src/content/videos/phpvigo/cb3fhly1sc4.md
@@ -0,0 +1,11 @@
+---
+sourceId: 'cB3fHLy1Sc4'
+groupId: 'phpvigo'
+groupName: 'PHPVigo'
+groupLogo: 'https://vigotech.org/images/php_vigo.jpg'
+title: 'Postgresql 101 - Eloy Coto (@eloycoto)'
+player: 'youtube'
+url: 'https://www.youtube.com/watch?v=cB3fHLy1Sc4'
+publishedAt: null
+thumbnail: 'https://i.ytimg.com/vi/cB3fHLy1Sc4/hqdefault.jpg?sqp=-oaymwEcCNACELwBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==&rs=AOn4CLDSW7RZ-5Js3SRGx_DRhD_DOmVFNA'
+---
diff --git a/src/content/videos/phpvigo/d2vqjesbl-e.md b/src/content/videos/phpvigo/d2vqjesbl-e.md
new file mode 100644
index 00000000..ab00e2ec
--- /dev/null
+++ b/src/content/videos/phpvigo/d2vqjesbl-e.md
@@ -0,0 +1,11 @@
+---
+sourceId: 'D2VqJesbL-E'
+groupId: 'phpvigo'
+groupName: 'PHPVigo'
+groupLogo: 'https://vigotech.org/images/php_vigo.jpg'
+title: 'Métodos mágicos II (Rolando Caldas)'
+player: 'youtube'
+url: 'https://www.youtube.com/watch?v=D2VqJesbL-E'
+publishedAt: null
+thumbnail: 'https://i.ytimg.com/vi/D2VqJesbL-E/hqdefault.jpg?sqp=-oaymwEcCNACELwBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==&rs=AOn4CLB7tNmWlw0qpA_VDX8u1vbWJzb1Ww'
+---
diff --git a/src/content/videos/phpvigo/dz8gidh9j9k.md b/src/content/videos/phpvigo/dz8gidh9j9k.md
new file mode 100644
index 00000000..811cc1da
--- /dev/null
+++ b/src/content/videos/phpvigo/dz8gidh9j9k.md
@@ -0,0 +1,11 @@
+---
+sourceId: 'Dz8giDh9j9k'
+groupId: 'phpvigo'
+groupName: 'PHPVigo'
+groupLogo: 'https://vigotech.org/images/php_vigo.jpg'
+title: 'Métodos mágicos (Rolando Caldas Sánchez)'
+player: 'youtube'
+url: 'https://www.youtube.com/watch?v=Dz8giDh9j9k'
+publishedAt: null
+thumbnail: 'https://i.ytimg.com/vi/Dz8giDh9j9k/hqdefault.jpg?sqp=-oaymwEcCNACELwBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==&rs=AOn4CLAGC99y4ElqX160PzN3yGaYus_ZbQ'
+---
diff --git a/src/content/videos/phpvigo/fzxgpe6ki3g.md b/src/content/videos/phpvigo/fzxgpe6ki3g.md
new file mode 100644
index 00000000..9ee6531c
--- /dev/null
+++ b/src/content/videos/phpvigo/fzxgpe6ki3g.md
@@ -0,0 +1,11 @@
+---
+sourceId: 'fZxGpE6ki3g'
+groupId: 'phpvigo'
+groupName: 'PHPVigo'
+groupLogo: 'https://vigotech.org/images/php_vigo.jpg'
+title: 'Conectar a MySQL correctamente (Jose Antonio González López)'
+player: 'youtube'
+url: 'https://www.youtube.com/watch?v=fZxGpE6ki3g'
+publishedAt: null
+thumbnail: 'https://i.ytimg.com/vi/fZxGpE6ki3g/hqdefault.jpg?sqp=-oaymwEcCNACELwBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==&rs=AOn4CLDxJjS-R39TORUJb-6cBUfDcobVKQ'
+---
diff --git a/src/content/videos/phpvigo/gibqyfj2k5g.md b/src/content/videos/phpvigo/gibqyfj2k5g.md
new file mode 100644
index 00000000..b407fd99
--- /dev/null
+++ b/src/content/videos/phpvigo/gibqyfj2k5g.md
@@ -0,0 +1,11 @@
+---
+sourceId: 'GIbQYfj2K5g'
+groupId: 'phpvigo'
+groupName: 'PHPVigo'
+groupLogo: 'https://vigotech.org/images/php_vigo.jpg'
+title: 'Blackfire.io: Mide tu performance (Ruben Gonzalez)'
+player: 'youtube'
+url: 'https://www.youtube.com/watch?v=GIbQYfj2K5g'
+publishedAt: null
+thumbnail: 'https://i.ytimg.com/vi/GIbQYfj2K5g/hqdefault.jpg?sqp=-oaymwEcCNACELwBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==&rs=AOn4CLAVU5Obcrrg3DvXxW6HFOaoOENIaA'
+---
diff --git a/src/content/videos/phpvigo/iyj-extcbyq.md b/src/content/videos/phpvigo/iyj-extcbyq.md
new file mode 100644
index 00000000..edc1e8f6
--- /dev/null
+++ b/src/content/videos/phpvigo/iyj-extcbyq.md
@@ -0,0 +1,11 @@
+---
+sourceId: 'iyj-exTcbyQ'
+groupId: 'phpvigo'
+groupName: 'PHPVigo'
+groupLogo: 'https://vigotech.org/images/php_vigo.jpg'
+title: 'PHPVigo #38: "Monta una API con ReactPHP" (Dev Streaming)'
+player: 'youtube'
+url: 'https://www.youtube.com/watch?v=iyj-exTcbyQ'
+publishedAt: 1596136540000
+thumbnail: 'https://i.ytimg.com/vi/iyj-exTcbyQ/hqdefault.jpg'
+---
diff --git a/src/content/videos/phpvigo/kojcoyysprm.md b/src/content/videos/phpvigo/kojcoyysprm.md
new file mode 100644
index 00000000..dc476b77
--- /dev/null
+++ b/src/content/videos/phpvigo/kojcoyysprm.md
@@ -0,0 +1,11 @@
+---
+sourceId: 'KOJcOyySPRM'
+groupId: 'phpvigo'
+groupName: 'PHPVigo'
+groupLogo: 'https://vigotech.org/images/php_vigo.jpg'
+title: 'Dónde está mi ñ'
+player: 'youtube'
+url: 'https://www.youtube.com/watch?v=KOJcOyySPRM'
+publishedAt: null
+thumbnail: 'https://i.ytimg.com/vi/KOJcOyySPRM/hqdefault.jpg?sqp=-oaymwEcCNACELwBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==&rs=AOn4CLBg70H4Q6gX7gdFRWKK5G-QybgAVg'
+---
diff --git a/src/content/videos/phpvigo/kwydgooyo2o.md b/src/content/videos/phpvigo/kwydgooyo2o.md
new file mode 100644
index 00000000..c69ad133
--- /dev/null
+++ b/src/content/videos/phpvigo/kwydgooyo2o.md
@@ -0,0 +1,11 @@
+---
+sourceId: 'KwydgooyO2o'
+groupId: 'phpvigo'
+groupName: 'PHPVigo'
+groupLogo: 'https://vigotech.org/images/php_vigo.jpg'
+title: 'Symfony 4 con David Negreira'
+player: 'youtube'
+url: 'https://www.youtube.com/watch?v=KwydgooyO2o'
+publishedAt: 1517558631000
+thumbnail: 'https://i.ytimg.com/vi/KwydgooyO2o/hqdefault.jpg'
+---
diff --git a/src/content/videos/phpvigo/loq7ztwd5ti.md b/src/content/videos/phpvigo/loq7ztwd5ti.md
new file mode 100644
index 00000000..9606009b
--- /dev/null
+++ b/src/content/videos/phpvigo/loq7ztwd5ti.md
@@ -0,0 +1,11 @@
+---
+sourceId: 'LOQ7zTWD5tI'
+groupId: 'phpvigo'
+groupName: 'PHPVigo'
+groupLogo: 'https://vigotech.org/images/php_vigo.jpg'
+title: 'Arrays y Js, vamos a jugar - David García (@tansitos)'
+player: 'youtube'
+url: 'https://www.youtube.com/watch?v=LOQ7zTWD5tI'
+publishedAt: null
+thumbnail: 'https://i.ytimg.com/vi/LOQ7zTWD5tI/hqdefault.jpg?sqp=-oaymwEcCNACELwBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==&rs=AOn4CLCuB-wsXHuzdqifnmuonX1-ZinHag'
+---
diff --git a/src/content/videos/phpvigo/lvk88gcu7-q.md b/src/content/videos/phpvigo/lvk88gcu7-q.md
new file mode 100644
index 00000000..93438b0a
--- /dev/null
+++ b/src/content/videos/phpvigo/lvk88gcu7-q.md
@@ -0,0 +1,11 @@
+---
+sourceId: 'LVK88Gcu7-Q'
+groupId: 'phpvigo'
+groupName: 'PHPVigo'
+groupLogo: 'https://vigotech.org/images/php_vigo.jpg'
+title: 'Preprocesadores CSS'
+player: 'youtube'
+url: 'https://www.youtube.com/watch?v=LVK88Gcu7-Q'
+publishedAt: null
+thumbnail: 'https://i.ytimg.com/vi/LVK88Gcu7-Q/hqdefault.jpg?sqp=-oaymwEcCNACELwBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==&rs=AOn4CLAZxyQEVNAVB5ZpfCCQTWS0nP8X0Q'
+---
diff --git a/src/content/videos/phpvigo/nbep64e8dzq.md b/src/content/videos/phpvigo/nbep64e8dzq.md
new file mode 100644
index 00000000..e253cf3f
--- /dev/null
+++ b/src/content/videos/phpvigo/nbep64e8dzq.md
@@ -0,0 +1,11 @@
+---
+sourceId: 'NbeP64e8DZQ'
+groupId: 'phpvigo'
+groupName: 'PHPVigo'
+groupLogo: 'https://vigotech.org/images/php_vigo.jpg'
+title: 'CSS Grid Layout: El futuro ya está aquí'
+player: 'youtube'
+url: 'https://www.youtube.com/watch?v=NbeP64e8DZQ'
+publishedAt: 1493754893000
+thumbnail: 'https://i.ytimg.com/vi/NbeP64e8DZQ/hqdefault.jpg'
+---
diff --git a/src/content/videos/phpvigo/nftbtvstshe.md b/src/content/videos/phpvigo/nftbtvstshe.md
new file mode 100644
index 00000000..94f254c3
--- /dev/null
+++ b/src/content/videos/phpvigo/nftbtvstshe.md
@@ -0,0 +1,11 @@
+---
+sourceId: 'NftbtvsTShE'
+groupId: 'phpvigo'
+groupName: 'PHPVigo'
+groupLogo: 'https://vigotech.org/images/php_vigo.jpg'
+title: 'Meetup #15: ¡No sin Composer! Carlos Goce (@carlosgoce)'
+player: 'youtube'
+url: 'https://www.youtube.com/watch?v=NftbtvsTShE'
+publishedAt: 1507036022000
+thumbnail: 'https://i.ytimg.com/vi/NftbtvsTShE/hqdefault.jpg'
+---
diff --git a/src/content/videos/phpvigo/nkrt5d-jzti.md b/src/content/videos/phpvigo/nkrt5d-jzti.md
new file mode 100644
index 00000000..f53ce938
--- /dev/null
+++ b/src/content/videos/phpvigo/nkrt5d-jzti.md
@@ -0,0 +1,11 @@
+---
+sourceId: 'Nkrt5d_jZtI'
+groupId: 'phpvigo'
+groupName: 'PHPVigo'
+groupLogo: 'https://vigotech.org/images/php_vigo.jpg'
+title: 'PHPVigo Drupal'
+player: 'youtube'
+url: 'https://www.youtube.com/watch?v=Nkrt5d_jZtI'
+publishedAt: null
+thumbnail: 'https://i.ytimg.com/vi/Nkrt5d_jZtI/hqdefault.jpg?sqp=-oaymwE2CNACELwBSFXyq4qpAygIARUAAIhCGAFwAcABBvABAfgB_gmAAtAFigIMCAAQARhNID8ofzAP&rs=AOn4CLDHkC74CJZAyeCbHjGJXkwxNuPpCg'
+---
diff --git a/src/content/videos/phpvigo/nxktclql-oy.md b/src/content/videos/phpvigo/nxktclql-oy.md
new file mode 100644
index 00000000..3dccf678
--- /dev/null
+++ b/src/content/videos/phpvigo/nxktclql-oy.md
@@ -0,0 +1,11 @@
+---
+sourceId: 'nxKtcLQl-OY'
+groupId: 'phpvigo'
+groupName: 'PHPVigo'
+groupLogo: 'https://vigotech.org/images/php_vigo.jpg'
+title: 'Resque: Workers Asíncronos (Sergio Carracedo)'
+player: 'youtube'
+url: 'https://www.youtube.com/watch?v=nxKtcLQl-OY'
+publishedAt: null
+thumbnail: 'https://i.ytimg.com/vi/nxKtcLQl-OY/hqdefault.jpg?sqp=-oaymwEcCNACELwBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==&rs=AOn4CLC-_AR9NEW52Z81WzNnRE_Q6Cb85Q'
+---
diff --git a/src/content/videos/phpvigo/o8-24tjp-2o.md b/src/content/videos/phpvigo/o8-24tjp-2o.md
new file mode 100644
index 00000000..0dcb22db
--- /dev/null
+++ b/src/content/videos/phpvigo/o8-24tjp-2o.md
@@ -0,0 +1,11 @@
+---
+sourceId: 'o8_24tjP-2o'
+groupId: 'phpvigo'
+groupName: 'PHPVigo'
+groupLogo: 'https://vigotech.org/images/php_vigo.jpg'
+title: 'Charla Introducción a Joomla por Pablo Arias - #PHPVigo Meetup #2'
+player: 'youtube'
+url: 'https://www.youtube.com/watch?v=o8_24tjP-2o'
+publishedAt: null
+thumbnail: 'https://i.ytimg.com/vi/o8_24tjP-2o/hqdefault.jpg?sqp=-oaymwE2CNACELwBSFXyq4qpAygIARUAAIhCGAFwAcABBvABAfgB_gmAAtAFigIMCAAQARhyIE0oMDAP&rs=AOn4CLA_0Rhm3bUv_7ced8oSnuMsGx-Tyg'
+---
diff --git a/src/content/videos/phpvigo/ouz-mqfccuy.md b/src/content/videos/phpvigo/ouz-mqfccuy.md
new file mode 100644
index 00000000..ddca1603
--- /dev/null
+++ b/src/content/videos/phpvigo/ouz-mqfccuy.md
@@ -0,0 +1,11 @@
+---
+sourceId: 'oUZ-mqFcCuY'
+groupId: 'phpvigo'
+groupName: 'PHPVigo'
+groupLogo: 'https://vigotech.org/images/php_vigo.jpg'
+title: 'Testing && Pizza - Álvaro Gómez (@lito_ordes)'
+player: 'youtube'
+url: 'https://www.youtube.com/watch?v=oUZ-mqFcCuY'
+publishedAt: 1517559810000
+thumbnail: 'https://i.ytimg.com/vi/oUZ-mqFcCuY/hqdefault.jpg'
+---
diff --git a/src/content/videos/phpvigo/p4vdylusqhw.md b/src/content/videos/phpvigo/p4vdylusqhw.md
new file mode 100644
index 00000000..43e469e1
--- /dev/null
+++ b/src/content/videos/phpvigo/p4vdylusqhw.md
@@ -0,0 +1,11 @@
+---
+sourceId: 'p4vdyLUsqHw'
+groupId: 'phpvigo'
+groupName: 'PHPVigo'
+groupLogo: 'https://vigotech.org/images/php_vigo.jpg'
+title: 'Encabezados HTTP de seguridade @rocasan_'
+player: 'youtube'
+url: 'https://www.youtube.com/watch?v=p4vdyLUsqHw'
+publishedAt: 1507017150000
+thumbnail: 'https://i.ytimg.com/vi/p4vdyLUsqHw/hqdefault.jpg'
+---
diff --git a/src/content/videos/phpvigo/q4vl54asnai.md b/src/content/videos/phpvigo/q4vl54asnai.md
new file mode 100644
index 00000000..c8ed6f17
--- /dev/null
+++ b/src/content/videos/phpvigo/q4vl54asnai.md
@@ -0,0 +1,11 @@
+---
+sourceId: 'q4Vl54AsnaI'
+groupId: 'phpvigo'
+groupName: 'PHPVigo'
+groupLogo: 'https://vigotech.org/images/php_vigo.jpg'
+title: 'Felicitacion PHPVigo 2016'
+player: 'youtube'
+url: 'https://www.youtube.com/watch?v=q4Vl54AsnaI'
+publishedAt: null
+thumbnail: 'https://i.ytimg.com/vi/q4Vl54AsnaI/hqdefault.jpg?sqp=-oaymwEcCNACELwBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==&rs=AOn4CLCwCw6I-BJMSiuQIGb4avXBV2gFgw'
+---
diff --git a/src/content/videos/phpvigo/qkrdzyq6oai.md b/src/content/videos/phpvigo/qkrdzyq6oai.md
new file mode 100644
index 00000000..9693c50e
--- /dev/null
+++ b/src/content/videos/phpvigo/qkrdzyq6oai.md
@@ -0,0 +1,11 @@
+---
+sourceId: 'QKRdzyq6oAI'
+groupId: 'phpvigo'
+groupName: 'PHPVigo'
+groupLogo: 'https://vigotech.org/images/php_vigo.jpg'
+title: 'Charla sobre Ansible por Orestes Carracedo - #PHPVigo Meetup#1'
+player: 'youtube'
+url: 'https://www.youtube.com/watch?v=QKRdzyq6oAI'
+publishedAt: null
+thumbnail: 'https://i.ytimg.com/vi/QKRdzyq6oAI/hqdefault.jpg?sqp=-oaymwEcCNACELwBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==&rs=AOn4CLCGt7gVnmq1tXYK-jXpAV-DuYK8Nw'
+---
diff --git a/src/content/videos/phpvigo/rffmsqrfml8.md b/src/content/videos/phpvigo/rffmsqrfml8.md
new file mode 100644
index 00000000..260bd612
--- /dev/null
+++ b/src/content/videos/phpvigo/rffmsqrfml8.md
@@ -0,0 +1,11 @@
+---
+sourceId: 'rffMsQRFml8'
+groupId: 'phpvigo'
+groupName: 'PHPVigo'
+groupLogo: 'https://vigotech.org/images/php_vigo.jpg'
+title: 'phpVigo AWS'
+player: 'youtube'
+url: 'https://www.youtube.com/watch?v=rffMsQRFml8'
+publishedAt: null
+thumbnail: 'https://i.ytimg.com/vi/rffMsQRFml8/hqdefault.jpg?sqp=-oaymwEcCNACELwBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==&rs=AOn4CLA0iJJ2Tl9zoTNom4Vysl1U4yumtQ'
+---
diff --git a/src/content/videos/phpvigo/sclgm6jitik.md b/src/content/videos/phpvigo/sclgm6jitik.md
new file mode 100644
index 00000000..9d0816a1
--- /dev/null
+++ b/src/content/videos/phpvigo/sclgm6jitik.md
@@ -0,0 +1,11 @@
+---
+sourceId: 'ScLGm6jitik'
+groupId: 'phpvigo'
+groupName: 'PHPVigo'
+groupLogo: 'https://vigotech.org/images/php_vigo.jpg'
+title: 'Meetup#7: AWS Reload y Despliegue con Deployer'
+player: 'youtube'
+url: 'https://www.youtube.com/watch?v=ScLGm6jitik'
+publishedAt: null
+thumbnail: 'https://i.ytimg.com/vi/ScLGm6jitik/hqdefault.jpg?sqp=-oaymwE2CNACELwBSFXyq4qpAygIARUAAIhCGAFwAcABBvABAfgB_gmAAtAFigIMCAAQARhEIFMocjAP&rs=AOn4CLCY7Abq3mniZSvU5kb4g6WvGOwcMg'
+---
diff --git a/src/content/videos/phpvigo/svqewpbjkva.md b/src/content/videos/phpvigo/svqewpbjkva.md
new file mode 100644
index 00000000..f252f44e
--- /dev/null
+++ b/src/content/videos/phpvigo/svqewpbjkva.md
@@ -0,0 +1,11 @@
+---
+sourceId: 'svqEwpbjkvA'
+groupId: 'phpvigo'
+groupName: 'PHPVigo'
+groupLogo: 'https://vigotech.org/images/php_vigo.jpg'
+title: '¿Nos hacen los tests ir más rápidos?'
+player: 'youtube'
+url: 'https://www.youtube.com/watch?v=svqEwpbjkvA'
+publishedAt: null
+thumbnail: 'https://i.ytimg.com/vi/svqEwpbjkvA/hqdefault.jpg?sqp=-oaymwE2CNACELwBSFXyq4qpAygIARUAAIhCGAFwAcABBvABAfgB_gmAAtAFigIMCAAQARh_IDkoEzAP&rs=AOn4CLBJSPaM_1TNibmEgwPElFJo7wNwlw'
+---
diff --git a/src/content/videos/phpvigo/tugzwmsf-mk.md b/src/content/videos/phpvigo/tugzwmsf-mk.md
new file mode 100644
index 00000000..8b2ab601
--- /dev/null
+++ b/src/content/videos/phpvigo/tugzwmsf-mk.md
@@ -0,0 +1,11 @@
+---
+sourceId: 'TuGZWmsf-Mk'
+groupId: 'phpvigo'
+groupName: 'PHPVigo'
+groupLogo: 'https://vigotech.org/images/php_vigo.jpg'
+title: 'Meetup #12: "Performance blackfire.io"'
+player: 'youtube'
+url: 'https://www.youtube.com/watch?v=TuGZWmsf-Mk'
+publishedAt: null
+thumbnail: 'https://i.ytimg.com/vi/TuGZWmsf-Mk/hqdefault.jpg?sqp=-oaymwEcCNACELwBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==&rs=AOn4CLDCaZxqEl9FVN2vSFBBWxiX9BUkLA'
+---
diff --git a/src/content/videos/phpvigo/txwbsvm2rx0.md b/src/content/videos/phpvigo/txwbsvm2rx0.md
new file mode 100644
index 00000000..fc9e2d9d
--- /dev/null
+++ b/src/content/videos/phpvigo/txwbsvm2rx0.md
@@ -0,0 +1,11 @@
+---
+sourceId: 'txWbsVM2Rx0'
+groupId: 'phpvigo'
+groupName: 'PHPVigo'
+groupLogo: 'https://vigotech.org/images/php_vigo.jpg'
+title: 'PHP Slim Api Rest (Fernando Freire)'
+player: 'youtube'
+url: 'https://www.youtube.com/watch?v=txWbsVM2Rx0'
+publishedAt: 1507035616000
+thumbnail: 'https://i.ytimg.com/vi/txWbsVM2Rx0/hqdefault.jpg'
+---
diff --git a/src/content/videos/phpvigo/uc1f88sgfji.md b/src/content/videos/phpvigo/uc1f88sgfji.md
new file mode 100644
index 00000000..6887f1cd
--- /dev/null
+++ b/src/content/videos/phpvigo/uc1f88sgfji.md
@@ -0,0 +1,11 @@
+---
+sourceId: 'uC1f88SGFJI'
+groupId: 'phpvigo'
+groupName: 'PHPVigo'
+groupLogo: 'https://vigotech.org/images/php_vigo.jpg'
+title: 'Facturascripts 2018 técnico'
+player: 'youtube'
+url: 'https://www.youtube.com/watch?v=uC1f88SGFJI'
+publishedAt: 1512029706000
+thumbnail: 'https://i.ytimg.com/vi/uC1f88SGFJI/hqdefault.jpg'
+---
diff --git a/src/content/videos/phpvigo/udzna9mbibw.md b/src/content/videos/phpvigo/udzna9mbibw.md
new file mode 100644
index 00000000..de70b508
--- /dev/null
+++ b/src/content/videos/phpvigo/udzna9mbibw.md
@@ -0,0 +1,11 @@
+---
+sourceId: 'uDzna9mbIBw'
+groupId: 'phpvigo'
+groupName: 'PHPVigo'
+groupLogo: 'https://vigotech.org/images/php_vigo.jpg'
+title: '"API REST" - Bueno Bonito Barato'
+player: 'youtube'
+url: 'https://www.youtube.com/watch?v=uDzna9mbIBw'
+publishedAt: null
+thumbnail: 'https://i.ytimg.com/vi/uDzna9mbIBw/hqdefault.jpg?sqp=-oaymwEcCNACELwBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==&rs=AOn4CLD87rlezpeLJjb4jf7F_7soXEt8rQ'
+---
diff --git a/src/content/videos/phpvigo/ufgsmaza42c.md b/src/content/videos/phpvigo/ufgsmaza42c.md
new file mode 100644
index 00000000..aa26274e
--- /dev/null
+++ b/src/content/videos/phpvigo/ufgsmaza42c.md
@@ -0,0 +1,11 @@
+---
+sourceId: 'ufGsMAzA42c'
+groupId: 'phpvigo'
+groupName: 'PHPVigo'
+groupLogo: 'https://vigotech.org/images/php_vigo.jpg'
+title: 'Rolando Caldas - Password Hash'
+player: 'youtube'
+url: 'https://www.youtube.com/watch?v=ufGsMAzA42c'
+publishedAt: 1512029162000
+thumbnail: 'https://i.ytimg.com/vi/ufGsMAzA42c/hqdefault.jpg'
+---
diff --git a/src/content/videos/phpvigo/uhpfamewhds.md b/src/content/videos/phpvigo/uhpfamewhds.md
new file mode 100644
index 00000000..65457a1d
--- /dev/null
+++ b/src/content/videos/phpvigo/uhpfamewhds.md
@@ -0,0 +1,11 @@
+---
+sourceId: 'UhPfaMEWHDs'
+groupId: 'phpvigo'
+groupName: 'PHPVigo'
+groupLogo: 'https://vigotech.org/images/php_vigo.jpg'
+title: 'Preprocesadores CSS'
+player: 'youtube'
+url: 'https://www.youtube.com/watch?v=UhPfaMEWHDs'
+publishedAt: null
+thumbnail: 'https://i.ytimg.com/vi/UhPfaMEWHDs/hqdefault.jpg?sqp=-oaymwEcCNACELwBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==&rs=AOn4CLCbBta5JoI1D297F15UgveADFbILg'
+---
diff --git a/src/content/videos/phpvigo/umssjhe5yg0.md b/src/content/videos/phpvigo/umssjhe5yg0.md
new file mode 100644
index 00000000..ffeb6c75
--- /dev/null
+++ b/src/content/videos/phpvigo/umssjhe5yg0.md
@@ -0,0 +1,11 @@
+---
+sourceId: 'umssjHE5yG0'
+groupId: 'phpvigo'
+groupName: 'PHPVigo'
+groupLogo: 'https://vigotech.org/images/php_vigo.jpg'
+title: 'Filter Input (@rolando_caldas)'
+player: 'youtube'
+url: 'https://www.youtube.com/watch?v=umssjHE5yG0'
+publishedAt: 1507017150000
+thumbnail: 'https://i.ytimg.com/vi/umssjHE5yG0/hqdefault.jpg'
+---
diff --git a/src/content/videos/phpvigo/vvbdoctin44.md b/src/content/videos/phpvigo/vvbdoctin44.md
new file mode 100644
index 00000000..23beba2c
--- /dev/null
+++ b/src/content/videos/phpvigo/vvbdoctin44.md
@@ -0,0 +1,11 @@
+---
+sourceId: 'VVbdoCTiN44'
+groupId: 'phpvigo'
+groupName: 'PHPVigo'
+groupLogo: 'https://vigotech.org/images/php_vigo.jpg'
+title: 'Shame on you PHP!! (Sergio Carracedo)'
+player: 'youtube'
+url: 'https://www.youtube.com/watch?v=VVbdoCTiN44'
+publishedAt: null
+thumbnail: 'https://i.ytimg.com/vi/VVbdoCTiN44/hqdefault.jpg?sqp=-oaymwEcCNACELwBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==&rs=AOn4CLAyWU65eV2OHnLt3U1waP5U1762Bw'
+---
diff --git a/src/content/videos/phpvigo/wyluexr7v-m.md b/src/content/videos/phpvigo/wyluexr7v-m.md
new file mode 100644
index 00000000..560e1733
--- /dev/null
+++ b/src/content/videos/phpvigo/wyluexr7v-m.md
@@ -0,0 +1,11 @@
+---
+sourceId: 'wyLUeXr7v_M'
+groupId: 'phpvigo'
+groupName: 'PHPVigo'
+groupLogo: 'https://vigotech.org/images/php_vigo.jpg'
+title: 'Meetup #12: "Gestionar un WP con 250k pv diarias"'
+player: 'youtube'
+url: 'https://www.youtube.com/watch?v=wyLUeXr7v_M'
+publishedAt: null
+thumbnail: 'https://i.ytimg.com/vi/wyLUeXr7v_M/hqdefault.jpg?sqp=-oaymwEcCNACELwBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==&rs=AOn4CLDR5EKmJtp6J6r5fuK0AZdg7OxliQ'
+---
diff --git a/src/content/videos/phpvigo/ylwj3n6hjxy.md b/src/content/videos/phpvigo/ylwj3n6hjxy.md
new file mode 100644
index 00000000..79b05f28
--- /dev/null
+++ b/src/content/videos/phpvigo/ylwj3n6hjxy.md
@@ -0,0 +1,11 @@
+---
+sourceId: 'ylWJ3n6HJXY'
+groupId: 'phpvigo'
+groupName: 'PHPVigo'
+groupLogo: 'https://vigotech.org/images/php_vigo.jpg'
+title: '2017 03 22 21 26 38'
+player: 'youtube'
+url: 'https://www.youtube.com/watch?v=ylWJ3n6HJXY'
+publishedAt: null
+thumbnail: 'https://i.ytimg.com/vi/ylWJ3n6HJXY/hqdefault.jpg?sqp=-oaymwEcCNACELwBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==&rs=AOn4CLBVIj8MrW35EvNS8tQz-9s84RiBuQ'
+---
diff --git a/src/content/videos/phpvigo/yzoyqg1niro.md b/src/content/videos/phpvigo/yzoyqg1niro.md
new file mode 100644
index 00000000..7fcaf40e
--- /dev/null
+++ b/src/content/videos/phpvigo/yzoyqg1niro.md
@@ -0,0 +1,11 @@
+---
+sourceId: 'yzoyQg1NIRo'
+groupId: 'phpvigo'
+groupName: 'PHPVigo'
+groupLogo: 'https://vigotech.org/images/php_vigo.jpg'
+title: 'PHP Traits (Carlos Goce)'
+player: 'youtube'
+url: 'https://www.youtube.com/watch?v=yzoyQg1NIRo'
+publishedAt: null
+thumbnail: 'https://i.ytimg.com/vi/yzoyQg1NIRo/hqdefault.jpg?sqp=-oaymwEcCNACELwBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==&rs=AOn4CLAZleBtC8u2W2mOjO3IJgk_VxOiSA'
+---
diff --git a/src/content/videos/phpvigo/z-k5iusjcdo.md b/src/content/videos/phpvigo/z-k5iusjcdo.md
new file mode 100644
index 00000000..edeecb0e
--- /dev/null
+++ b/src/content/videos/phpvigo/z-k5iusjcdo.md
@@ -0,0 +1,11 @@
+---
+sourceId: 'z_K5iuSjCDo'
+groupId: 'phpvigo'
+groupName: 'PHPVigo'
+groupLogo: 'https://vigotech.org/images/php_vigo.jpg'
+title: 'PHPVigo 39: "Crea tu propia librería de componentes Vue. From scratch to NPM"'
+player: 'youtube'
+url: 'https://www.youtube.com/watch?v=z_K5iuSjCDo'
+publishedAt: 1601453780000
+thumbnail: 'https://i.ytimg.com/vi/z_K5iuSjCDo/hqdefault.jpg'
+---
diff --git a/src/content/videos/phpvigo/zix6z-xyn90.md b/src/content/videos/phpvigo/zix6z-xyn90.md
new file mode 100644
index 00000000..4d666c37
--- /dev/null
+++ b/src/content/videos/phpvigo/zix6z-xyn90.md
@@ -0,0 +1,11 @@
+---
+sourceId: 'ZIX6z-xYN90'
+groupId: 'phpvigo'
+groupName: 'PHPVigo'
+groupLogo: 'https://vigotech.org/images/php_vigo.jpg'
+title: 'Jenkins: Deja ya de hacerlo a mano!" - Santiago Rodriguez Collazo'
+player: 'youtube'
+url: 'https://www.youtube.com/watch?v=ZIX6z-xYN90'
+publishedAt: null
+thumbnail: 'https://i.ytimg.com/vi/ZIX6z-xYN90/hqdefault.jpg?sqp=-oaymwEcCNACELwBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==&rs=AOn4CLASjqzUD7KkZyOiE0uasojGW6SVyw'
+---
diff --git a/src/content/videos/phpvigo/zizo5kqm-ku.md b/src/content/videos/phpvigo/zizo5kqm-ku.md
new file mode 100644
index 00000000..870769c6
--- /dev/null
+++ b/src/content/videos/phpvigo/zizo5kqm-ku.md
@@ -0,0 +1,11 @@
+---
+sourceId: 'ziZO5KQM_KU'
+groupId: 'phpvigo'
+groupName: 'PHPVigo'
+groupLogo: 'https://vigotech.org/images/php_vigo.jpg'
+title: 'PHPVigo #37 - La nueva normalidad dev stream'
+player: 'youtube'
+url: 'https://www.youtube.com/watch?v=ziZO5KQM_KU'
+publishedAt: 1595059609000
+thumbnail: 'https://i.ytimg.com/vi/ziZO5KQM_KU/hqdefault.jpg'
+---
diff --git a/src/content/videos/pythonvigo/09hftif-fae.md b/src/content/videos/pythonvigo/09hftif-fae.md
new file mode 100644
index 00000000..3d454fa7
--- /dev/null
+++ b/src/content/videos/pythonvigo/09hftif-fae.md
@@ -0,0 +1,11 @@
+---
+sourceId: '09hfTif_FaE'
+groupId: 'pythonvigo'
+groupName: 'PythonVigo'
+groupLogo: 'https://vigotech.org/images/python_vigo.png'
+title: 'Algoritmo Binary Search, por Antón Yuste'
+player: 'youtube'
+url: 'https://www.youtube.com/watch?v=09hfTif_FaE'
+publishedAt: null
+thumbnail: 'https://i.ytimg.com/vi/09hfTif_FaE/hqdefault.jpg?sqp=-oaymwEcCNACELwBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==&rs=AOn4CLAtc4l81hkA1kWFDPAJ2RNMq-skow'
+---
diff --git a/src/content/videos/pythonvigo/1d7vqkrgdt4.md b/src/content/videos/pythonvigo/1d7vqkrgdt4.md
new file mode 100644
index 00000000..e720ca6c
--- /dev/null
+++ b/src/content/videos/pythonvigo/1d7vqkrgdt4.md
@@ -0,0 +1,11 @@
+---
+sourceId: '1D7VQKRgDT4'
+groupId: 'pythonvigo'
+groupName: 'PythonVigo'
+groupLogo: 'https://vigotech.org/images/python_vigo.png'
+title: 'Type Hinting básico, por Xurxo Fresco'
+player: 'youtube'
+url: 'https://www.youtube.com/watch?v=1D7VQKRgDT4'
+publishedAt: 1507017987000
+thumbnail: 'https://i.ytimg.com/vi/1D7VQKRgDT4/hqdefault.jpg'
+---
diff --git a/src/content/videos/pythonvigo/2qqrao0zioc.md b/src/content/videos/pythonvigo/2qqrao0zioc.md
new file mode 100644
index 00000000..f6230bb2
--- /dev/null
+++ b/src/content/videos/pythonvigo/2qqrao0zioc.md
@@ -0,0 +1,11 @@
+---
+sourceId: '2qQraO0ZIoc'
+groupId: 'pythonvigo'
+groupName: 'PythonVigo'
+groupLogo: 'https://vigotech.org/images/python_vigo.png'
+title: 'Acto de apertura PyConEs'
+player: 'youtube'
+url: 'https://www.youtube.com/watch?v=2qQraO0ZIoc'
+publishedAt: 1727370343000
+thumbnail: 'https://i.ytimg.com/vi/2qQraO0ZIoc/hqdefault.jpg'
+---
diff --git a/src/content/videos/pythonvigo/2x72htztglu.md b/src/content/videos/pythonvigo/2x72htztglu.md
new file mode 100644
index 00000000..b1374c89
--- /dev/null
+++ b/src/content/videos/pythonvigo/2x72htztglu.md
@@ -0,0 +1,11 @@
+---
+sourceId: '2X72HTZTgLU'
+groupId: 'pythonvigo'
+groupName: 'PythonVigo'
+groupLogo: 'https://vigotech.org/images/python_vigo.png'
+title: 'Introducción a Machine Learning con Python - Xurxo Fresco - PyDay'
+player: 'youtube'
+url: 'https://www.youtube.com/watch?v=2X72HTZTgLU'
+publishedAt: null
+thumbnail: 'https://i.ytimg.com/vi/2X72HTZTgLU/hqdefault.jpg?sqp=-oaymwE2CNACELwBSFXyq4qpAygIARUAAIhCGAFwAcABBvABAfgB_giAAtAFigIMCAAQARhlIGUoZTAP&rs=AOn4CLCanPqFwTs6IwWcitfCLgzO82WNuQ'
+---
diff --git a/src/content/videos/pythonvigo/49klm6h8sg8.md b/src/content/videos/pythonvigo/49klm6h8sg8.md
new file mode 100644
index 00000000..419c994b
--- /dev/null
+++ b/src/content/videos/pythonvigo/49klm6h8sg8.md
@@ -0,0 +1,11 @@
+---
+sourceId: '49KlM6h8sg8'
+groupId: 'pythonvigo'
+groupName: 'PythonVigo'
+groupLogo: 'https://vigotech.org/images/python_vigo.png'
+title: 'Acto de apertura PyConEs'
+player: 'youtube'
+url: 'https://www.youtube.com/watch?v=49KlM6h8sg8'
+publishedAt: 1727372003000
+thumbnail: 'https://i.ytimg.com/vi/49KlM6h8sg8/hqdefault.jpg'
+---
diff --git a/src/content/videos/pythonvigo/6nirycubxpk.md b/src/content/videos/pythonvigo/6nirycubxpk.md
new file mode 100644
index 00000000..094fadd6
--- /dev/null
+++ b/src/content/videos/pythonvigo/6nirycubxpk.md
@@ -0,0 +1,11 @@
+---
+sourceId: '6niRYcubxPk'
+groupId: 'pythonvigo'
+groupName: 'PythonVigo'
+groupLogo: 'https://vigotech.org/images/python_vigo.png'
+title: 'Entornos Interactivos en python'
+player: 'youtube'
+url: 'https://www.youtube.com/watch?v=6niRYcubxPk'
+publishedAt: null
+thumbnail: 'https://i.ytimg.com/vi/6niRYcubxPk/hqdefault.jpg?sqp=-oaymwEcCNACELwBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==&rs=AOn4CLA1w3xhPuYzyx7hsC_TIWce9lscLw'
+---
diff --git a/src/content/videos/pythonvigo/7u7veo8ahlk.md b/src/content/videos/pythonvigo/7u7veo8ahlk.md
new file mode 100644
index 00000000..3d0732c8
--- /dev/null
+++ b/src/content/videos/pythonvigo/7u7veo8ahlk.md
@@ -0,0 +1,11 @@
+---
+sourceId: '7U7vEO8AHlk'
+groupId: 'pythonvigo'
+groupName: 'PythonVigo'
+groupLogo: 'https://vigotech.org/images/python_vigo.png'
+title: 'Cómo evitar alucinaciones en ChatGPT con la arquitectura RAG por Maryna Bogdan'
+player: 'youtube'
+url: 'https://www.youtube.com/watch?v=7U7vEO8AHlk'
+publishedAt: 1740598943000
+thumbnail: 'https://i.ytimg.com/vi/7U7vEO8AHlk/hqdefault.jpg'
+---
diff --git a/src/content/videos/pythonvigo/9dptfapk8co.md b/src/content/videos/pythonvigo/9dptfapk8co.md
new file mode 100644
index 00000000..dd3c5cd8
--- /dev/null
+++ b/src/content/videos/pythonvigo/9dptfapk8co.md
@@ -0,0 +1,11 @@
+---
+sourceId: '9DPtfApk8co'
+groupId: 'pythonvigo'
+groupName: 'PythonVigo'
+groupLogo: 'https://vigotech.org/images/python_vigo.png'
+title: 'Emisión en directo Python Vigo'
+player: 'youtube'
+url: 'https://www.youtube.com/watch?v=9DPtfApk8co'
+publishedAt: null
+thumbnail: 'https://i.ytimg.com/vi/9DPtfApk8co/hqdefault.jpg?sqp=-oaymwEcCNACELwBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==&rs=AOn4CLDgmyKHjMuveU_qMDDha1S5pDwHpg'
+---
diff --git a/src/content/videos/pythonvigo/9p7qyb7leba.md b/src/content/videos/pythonvigo/9p7qyb7leba.md
new file mode 100644
index 00000000..c8af5c54
--- /dev/null
+++ b/src/content/videos/pythonvigo/9p7qyb7leba.md
@@ -0,0 +1,11 @@
+---
+sourceId: '9P7qyb7leBA'
+groupId: 'pythonvigo'
+groupName: 'PythonVigo'
+groupLogo: 'https://vigotech.org/images/python_vigo.png'
+title: 'Fixtures and factories by Hector Cantó'
+player: 'youtube'
+url: 'https://www.youtube.com/watch?v=9P7qyb7leBA'
+publishedAt: 1703361330000
+thumbnail: 'https://i.ytimg.com/vi/9P7qyb7leBA/hqdefault.jpg'
+---
diff --git a/src/content/videos/pythonvigo/cfq-1h7bxjk.md b/src/content/videos/pythonvigo/cfq-1h7bxjk.md
new file mode 100644
index 00000000..f20bc85f
--- /dev/null
+++ b/src/content/videos/pythonvigo/cfq-1h7bxjk.md
@@ -0,0 +1,11 @@
+---
+sourceId: 'cfQ-1H7bXjk'
+groupId: 'pythonvigo'
+groupName: 'PythonVigo'
+groupLogo: 'https://vigotech.org/images/python_vigo.png'
+title: 'Mira mamá, sin ifs - Miguel González'
+player: 'youtube'
+url: 'https://www.youtube.com/watch?v=cfQ-1H7bXjk'
+publishedAt: 1507036217000
+thumbnail: 'https://i.ytimg.com/vi/cfQ-1H7bXjk/hqdefault.jpg'
+---
diff --git a/src/content/videos/pythonvigo/d5vmtg95ov0.md b/src/content/videos/pythonvigo/d5vmtg95ov0.md
new file mode 100644
index 00000000..f6b5b016
--- /dev/null
+++ b/src/content/videos/pythonvigo/d5vmtg95ov0.md
@@ -0,0 +1,11 @@
+---
+sourceId: 'D5vmTg95Ov0'
+groupId: 'pythonvigo'
+groupName: 'PythonVigo'
+groupLogo: 'https://vigotech.org/images/python_vigo.png'
+title: 'Python 3, Primeros pasos.'
+player: 'youtube'
+url: 'https://www.youtube.com/watch?v=D5vmTg95Ov0'
+publishedAt: null
+thumbnail: 'https://i.ytimg.com/vi/D5vmTg95Ov0/hqdefault.jpg?sqp=-oaymwE2CNACELwBSFXyq4qpAygIARUAAIhCGAFwAcABBvABAfgB_gmAAtAFigIMCAAQARhyIFIoQzAP&rs=AOn4CLD8OPfx-iMks95It8zfyyhVoyEkJw'
+---
diff --git a/src/content/videos/pythonvigo/d7y88pmfnoe.md b/src/content/videos/pythonvigo/d7y88pmfnoe.md
new file mode 100644
index 00000000..ec9ef489
--- /dev/null
+++ b/src/content/videos/pythonvigo/d7y88pmfnoe.md
@@ -0,0 +1,11 @@
+---
+sourceId: 'd7y88pMfNoE'
+groupId: 'pythonvigo'
+groupName: 'PythonVigo'
+groupLogo: 'https://vigotech.org/images/python_vigo.png'
+title: '¡Eureka! (Python y ciencia) - ¡Eureka! (Python y ciencia) - PyDay Galicia'
+player: 'youtube'
+url: 'https://www.youtube.com/watch?v=d7y88pMfNoE'
+publishedAt: null
+thumbnail: 'https://i.ytimg.com/vi/d7y88pMfNoE/hqdefault.jpg?sqp=-oaymwE2CNACELwBSFXyq4qpAygIARUAAIhCGAFwAcABBvABAfgB_giAAtAFigIMCAAQARhyIFMoLDAP&rs=AOn4CLBq1FaDYAm_rsvqafEwVWN00BIw_w'
+---
diff --git a/src/content/videos/pythonvigo/ef4lltomzkw.md b/src/content/videos/pythonvigo/ef4lltomzkw.md
new file mode 100644
index 00000000..ab9393c0
--- /dev/null
+++ b/src/content/videos/pythonvigo/ef4lltomzkw.md
@@ -0,0 +1,11 @@
+---
+sourceId: 'ef4LLtomZKw'
+groupId: 'pythonvigo'
+groupName: 'PythonVigo'
+groupLogo: 'https://vigotech.org/images/python_vigo.png'
+title: 'PythonVigo - oklog - José COrral'
+player: 'youtube'
+url: 'https://www.youtube.com/watch?v=ef4LLtomZKw'
+publishedAt: null
+thumbnail: 'https://i.ytimg.com/vi/ef4LLtomZKw/hqdefault.jpg?sqp=-oaymwEcCNACELwBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==&rs=AOn4CLDQpQmcoYgVML2bqJ4VnCyRGVQwBw'
+---
diff --git a/src/content/videos/pythonvigo/ftzawsabxc0.md b/src/content/videos/pythonvigo/ftzawsabxc0.md
new file mode 100644
index 00000000..04bea1e6
--- /dev/null
+++ b/src/content/videos/pythonvigo/ftzawsabxc0.md
@@ -0,0 +1,11 @@
+---
+sourceId: 'fTZAWsABXc0'
+groupId: 'pythonvigo'
+groupName: 'PythonVigo'
+groupLogo: 'https://vigotech.org/images/python_vigo.png'
+title: 'Creando tu propio simulador cuántico en 200 líneas por Ismael Faro'
+player: 'youtube'
+url: 'https://www.youtube.com/watch?v=fTZAWsABXc0'
+publishedAt: 1594925459000
+thumbnail: 'https://i.ytimg.com/vi/fTZAWsABXc0/hqdefault.jpg'
+---
diff --git a/src/content/videos/pythonvigo/fwgppsiyg-o.md b/src/content/videos/pythonvigo/fwgppsiyg-o.md
new file mode 100644
index 00000000..bb25d65e
--- /dev/null
+++ b/src/content/videos/pythonvigo/fwgppsiyg-o.md
@@ -0,0 +1,11 @@
+---
+sourceId: 'FwgpPsiYg_o'
+groupId: 'pythonvigo'
+groupName: 'PythonVigo'
+groupLogo: 'https://vigotech.org/images/python_vigo.png'
+title: 'PythonVigo - jython - Antón R. Yuste'
+player: 'youtube'
+url: 'https://www.youtube.com/watch?v=FwgpPsiYg_o'
+publishedAt: null
+thumbnail: 'https://i.ytimg.com/vi/FwgpPsiYg_o/hqdefault.jpg?sqp=-oaymwEcCNACELwBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==&rs=AOn4CLC_l6jUKGydJ7D_J0NIhOfpkdoTew'
+---
diff --git a/src/content/videos/pythonvigo/gqvhybceimy.md b/src/content/videos/pythonvigo/gqvhybceimy.md
new file mode 100644
index 00000000..096ad77d
--- /dev/null
+++ b/src/content/videos/pythonvigo/gqvhybceimy.md
@@ -0,0 +1,11 @@
+---
+sourceId: 'gqvhYBCeiMY'
+groupId: 'pythonvigo'
+groupName: 'PythonVigo'
+groupLogo: 'https://vigotech.org/images/python_vigo.png'
+title: 'Docker en producción - José Corral'
+player: 'youtube'
+url: 'https://www.youtube.com/watch?v=gqvhYBCeiMY'
+publishedAt: 1507036364000
+thumbnail: 'https://i.ytimg.com/vi/gqvhYBCeiMY/hqdefault.jpg'
+---
diff --git a/src/content/videos/pythonvigo/hjx-lqllrhw.md b/src/content/videos/pythonvigo/hjx-lqllrhw.md
new file mode 100644
index 00000000..9ff19e02
--- /dev/null
+++ b/src/content/videos/pythonvigo/hjx-lqllrhw.md
@@ -0,0 +1,11 @@
+---
+sourceId: 'hjx-lqLlrhw'
+groupId: 'pythonvigo'
+groupName: 'PythonVigo'
+groupLogo: 'https://vigotech.org/images/python_vigo.png'
+title: 'PythonVigo - David de la Iglesia'
+player: 'youtube'
+url: 'https://www.youtube.com/watch?v=hjx-lqLlrhw'
+publishedAt: null
+thumbnail: 'https://i.ytimg.com/vi/hjx-lqLlrhw/hqdefault.jpg?sqp=-oaymwEcCNACELwBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==&rs=AOn4CLAjtLKb34cFte7DIwqbViR3Kqh9vA'
+---
diff --git a/src/content/videos/pythonvigo/hqxbvk4vi9m.md b/src/content/videos/pythonvigo/hqxbvk4vi9m.md
new file mode 100644
index 00000000..da529167
--- /dev/null
+++ b/src/content/videos/pythonvigo/hqxbvk4vi9m.md
@@ -0,0 +1,11 @@
+---
+sourceId: 'hqXBVk4vI9M'
+groupId: 'pythonvigo'
+groupName: 'PythonVigo'
+groupLogo: 'https://vigotech.org/images/python_vigo.png'
+title: 'Python bajo el agua. Aplicaciones python para vehículos submarinos por Ignacio González Liaño'
+player: 'youtube'
+url: 'https://www.youtube.com/watch?v=hqXBVk4vI9M'
+publishedAt: 1740078265000
+thumbnail: 'https://i.ytimg.com/vi/hqXBVk4vI9M/hqdefault.jpg'
+---
diff --git a/src/content/videos/pythonvigo/iy-6vy-m60y.md b/src/content/videos/pythonvigo/iy-6vy-m60y.md
new file mode 100644
index 00000000..fefb784b
--- /dev/null
+++ b/src/content/videos/pythonvigo/iy-6vy-m60y.md
@@ -0,0 +1,11 @@
+---
+sourceId: 'IY_6vY-M60Y'
+groupId: 'pythonvigo'
+groupName: 'PythonVigo'
+groupLogo: 'https://vigotech.org/images/python_vigo.png'
+title: 'Metodos magicos python'
+player: 'youtube'
+url: 'https://www.youtube.com/watch?v=IY_6vY-M60Y'
+publishedAt: null
+thumbnail: 'https://i.ytimg.com/vi/IY_6vY-M60Y/hqdefault.jpg?sqp=-oaymwE2CNACELwBSFXyq4qpAygIARUAAIhCGAFwAcABBvABAfgB_gmAAtAFigIMCAAQARhyIE0oQTAP&rs=AOn4CLBOCObX4S7Gdwwv5wSAhCSwhyKBOw'
+---
diff --git a/src/content/videos/pythonvigo/l8org4kzboi.md b/src/content/videos/pythonvigo/l8org4kzboi.md
new file mode 100644
index 00000000..7a9c626b
--- /dev/null
+++ b/src/content/videos/pythonvigo/l8org4kzboi.md
@@ -0,0 +1,11 @@
+---
+sourceId: 'l8ORg4kzBoI'
+groupId: 'pythonvigo'
+groupName: 'PythonVigo'
+groupLogo: 'https://vigotech.org/images/python_vigo.png'
+title: 'Resolviendo la kata Args con TDD, por Javier Sánchez'
+player: 'youtube'
+url: 'https://www.youtube.com/watch?v=l8ORg4kzBoI'
+publishedAt: null
+thumbnail: 'https://i.ytimg.com/vi/l8ORg4kzBoI/hqdefault.jpg?sqp=-oaymwEcCNACELwBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==&rs=AOn4CLD7mHoa5HQQnd9ui-U3RRPPw-iPtQ'
+---
diff --git a/src/content/videos/pythonvigo/lms4x-1cz-c.md b/src/content/videos/pythonvigo/lms4x-1cz-c.md
new file mode 100644
index 00000000..55a1d08d
--- /dev/null
+++ b/src/content/videos/pythonvigo/lms4x-1cz-c.md
@@ -0,0 +1,11 @@
+---
+sourceId: 'lmS4x_1Cz-c'
+groupId: 'pythonvigo'
+groupName: 'PythonVigo'
+groupLogo: 'https://vigotech.org/images/python_vigo.png'
+title: 'PythonVigo - logging - Miguel Gonzalez'
+player: 'youtube'
+url: 'https://www.youtube.com/watch?v=lmS4x_1Cz-c'
+publishedAt: null
+thumbnail: 'https://i.ytimg.com/vi/lmS4x_1Cz-c/hqdefault.jpg?sqp=-oaymwEcCNACELwBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==&rs=AOn4CLBSt2aW1O2wsVXjO222gTxP88CdRg'
+---
diff --git a/src/content/videos/pythonvigo/m8s3styumfs.md b/src/content/videos/pythonvigo/m8s3styumfs.md
new file mode 100644
index 00000000..eeba4074
--- /dev/null
+++ b/src/content/videos/pythonvigo/m8s3styumfs.md
@@ -0,0 +1,11 @@
+---
+sourceId: 'M8s3styUMFs'
+groupId: 'pythonvigo'
+groupName: 'PythonVigo'
+groupLogo: 'https://vigotech.org/images/python_vigo.png'
+title: 'Acto de apertura PyConEs'
+player: 'youtube'
+url: 'https://www.youtube.com/watch?v=M8s3styUMFs'
+publishedAt: 1705320052000
+thumbnail: 'https://i.ytimg.com/vi/M8s3styUMFs/hqdefault.jpg'
+---
diff --git a/src/content/videos/pythonvigo/micqgdqrzxm.md b/src/content/videos/pythonvigo/micqgdqrzxm.md
new file mode 100644
index 00000000..01848f25
--- /dev/null
+++ b/src/content/videos/pythonvigo/micqgdqrzxm.md
@@ -0,0 +1,11 @@
+---
+sourceId: 'miCqgdqrZXM'
+groupId: 'pythonvigo'
+groupName: 'PythonVigo'
+groupLogo: 'https://vigotech.org/images/python_vigo.png'
+title: 'Acto de apertura PyConEs'
+player: 'youtube'
+url: 'https://www.youtube.com/watch?v=miCqgdqrZXM'
+publishedAt: 1727420401000
+thumbnail: 'https://i.ytimg.com/vi/miCqgdqrZXM/hqdefault.jpg'
+---
diff --git a/src/content/videos/pythonvigo/npstutu8qxc.md b/src/content/videos/pythonvigo/npstutu8qxc.md
new file mode 100644
index 00000000..94853101
--- /dev/null
+++ b/src/content/videos/pythonvigo/npstutu8qxc.md
@@ -0,0 +1,11 @@
+---
+sourceId: 'NPsTUtU8QXc'
+groupId: 'pythonvigo'
+groupName: 'PythonVigo'
+groupLogo: 'https://vigotech.org/images/python_vigo.png'
+title: 'Emisión en directo Python Vigo'
+player: 'youtube'
+url: 'https://www.youtube.com/watch?v=NPsTUtU8QXc'
+publishedAt: null
+thumbnail: 'https://i.ytimg.com/vi/NPsTUtU8QXc/hqdefault.jpg?sqp=-oaymwEcCNACELwBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==&rs=AOn4CLCbFI-m2bKGPIJ0iYTbLTewfo8OcA'
+---
diff --git a/src/content/videos/pythonvigo/omst3ju-rjq.md b/src/content/videos/pythonvigo/omst3ju-rjq.md
new file mode 100644
index 00000000..a2799ecf
--- /dev/null
+++ b/src/content/videos/pythonvigo/omst3ju-rjq.md
@@ -0,0 +1,11 @@
+---
+sourceId: 'oMst3JU-RjQ'
+groupId: 'pythonvigo'
+groupName: 'PythonVigo'
+groupLogo: 'https://vigotech.org/images/python_vigo.png'
+title: 'Measure all the things'
+player: 'youtube'
+url: 'https://www.youtube.com/watch?v=oMst3JU-RjQ'
+publishedAt: null
+thumbnail: 'https://i.ytimg.com/vi/oMst3JU-RjQ/hqdefault.jpg?sqp=-oaymwEcCNACELwBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==&rs=AOn4CLCSpe5sjXUhTGX6yav9iQo7T468nA'
+---
diff --git a/src/content/videos/pythonvigo/phkmzaax3ha.md b/src/content/videos/pythonvigo/phkmzaax3ha.md
new file mode 100644
index 00000000..9faa599a
--- /dev/null
+++ b/src/content/videos/pythonvigo/phkmzaax3ha.md
@@ -0,0 +1,11 @@
+---
+sourceId: 'PhkMZaAX3HA'
+groupId: 'pythonvigo'
+groupName: 'PythonVigo'
+groupLogo: 'https://vigotech.org/images/python_vigo.png'
+title: 'Tinkering with CLI: Refining your terminal toolbox with pipx por Daniel Sanchez'
+player: 'youtube'
+url: 'https://www.youtube.com/watch?v=PhkMZaAX3HA'
+publishedAt: 1740586740000
+thumbnail: 'https://i.ytimg.com/vi/PhkMZaAX3HA/hqdefault.jpg'
+---
diff --git a/src/content/videos/pythonvigo/pw97r0eo7so.md b/src/content/videos/pythonvigo/pw97r0eo7so.md
new file mode 100644
index 00000000..e18c590a
--- /dev/null
+++ b/src/content/videos/pythonvigo/pw97r0eo7so.md
@@ -0,0 +1,11 @@
+---
+sourceId: 'pw97r0EO7So'
+groupId: 'pythonvigo'
+groupName: 'PythonVigo'
+groupLogo: 'https://vigotech.org/images/python_vigo.png'
+title: 'Emisión en directo Python Vigo'
+player: 'youtube'
+url: 'https://www.youtube.com/watch?v=pw97r0EO7So'
+publishedAt: null
+thumbnail: 'https://i.ytimg.com/vi/pw97r0EO7So/hqdefault.jpg?sqp=-oaymwEcCNACELwBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==&rs=AOn4CLAfcweT49X8Elu7U490AlwTiSeOmw'
+---
diff --git a/src/content/videos/pythonvigo/q7c9-yq6wk.md b/src/content/videos/pythonvigo/q7c9-yq6wk.md
new file mode 100644
index 00000000..84aadafb
--- /dev/null
+++ b/src/content/videos/pythonvigo/q7c9-yq6wk.md
@@ -0,0 +1,11 @@
+---
+sourceId: 'Q7C9-_yq6wk'
+groupId: 'pythonvigo'
+groupName: 'PythonVigo'
+groupLogo: 'https://vigotech.org/images/python_vigo.png'
+title: 'Emisión en directo Python Vigo'
+player: 'youtube'
+url: 'https://www.youtube.com/watch?v=Q7C9-_yq6wk'
+publishedAt: null
+thumbnail: 'https://i.ytimg.com/vi/Q7C9-_yq6wk/hqdefault.jpg?sqp=-oaymwEcCNACELwBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==&rs=AOn4CLAa61AJjjj7Oa4RWFppffcE_YnS9g'
+---
diff --git a/src/content/videos/pythonvigo/q9c0dqteyc8.md b/src/content/videos/pythonvigo/q9c0dqteyc8.md
new file mode 100644
index 00000000..d1a0a123
--- /dev/null
+++ b/src/content/videos/pythonvigo/q9c0dqteyc8.md
@@ -0,0 +1,11 @@
+---
+sourceId: 'Q9c0dQTEyc8'
+groupId: 'pythonvigo'
+groupName: 'PythonVigo'
+groupLogo: 'https://vigotech.org/images/python_vigo.png'
+title: 'Codenamize: presentación de la librería. Por José Juan Montes.'
+player: 'youtube'
+url: 'https://www.youtube.com/watch?v=Q9c0dQTEyc8'
+publishedAt: null
+thumbnail: 'https://i.ytimg.com/vi/Q9c0dQTEyc8/hqdefault.jpg?sqp=-oaymwEcCNACELwBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==&rs=AOn4CLDA6OfQpU2glbXbXnLFOos03UDA2Q'
+---
diff --git a/src/content/videos/pythonvigo/qfxsn-fc0nq.md b/src/content/videos/pythonvigo/qfxsn-fc0nq.md
new file mode 100644
index 00000000..47a0cc4d
--- /dev/null
+++ b/src/content/videos/pythonvigo/qfxsn-fc0nq.md
@@ -0,0 +1,11 @@
+---
+sourceId: 'QfXsn_fC0NQ'
+groupId: 'pythonvigo'
+groupName: 'PythonVigo'
+groupLogo: 'https://vigotech.org/images/python_vigo.png'
+title: '#GameDev at Python Vigo'
+player: 'youtube'
+url: 'https://www.youtube.com/watch?v=QfXsn_fC0NQ'
+publishedAt: null
+thumbnail: 'https://i.ytimg.com/vi/QfXsn_fC0NQ/hqdefault.jpg?sqp=-oaymwEcCNACELwBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==&rs=AOn4CLDtCpe3z0_pxaODGZ2LzUExeeAeiw'
+---
diff --git a/src/content/videos/pythonvigo/qwf0qd26gwm.md b/src/content/videos/pythonvigo/qwf0qd26gwm.md
new file mode 100644
index 00000000..6ac035a3
--- /dev/null
+++ b/src/content/videos/pythonvigo/qwf0qd26gwm.md
@@ -0,0 +1,11 @@
+---
+sourceId: 'QWF0qd26gWM'
+groupId: 'pythonvigo'
+groupName: 'PythonVigo'
+groupLogo: 'https://vigotech.org/images/python_vigo.png'
+title: 'Agile, Scrum y Kanban - Pepe Doval - PyDay Galicia'
+player: 'youtube'
+url: 'https://www.youtube.com/watch?v=QWF0qd26gWM'
+publishedAt: null
+thumbnail: 'https://i.ytimg.com/vi/QWF0qd26gWM/hqdefault.jpg?sqp=-oaymwE2CNACELwBSFXyq4qpAygIARUAAIhCGAFwAcABBvABAfgB_giAAtAFigIMCAAQARhlIGUoZTAP&rs=AOn4CLDL2YCJAQN-mmPr1iSGQngAtG8BIg'
+---
diff --git a/src/content/videos/pythonvigo/qwhoyvluk-u.md b/src/content/videos/pythonvigo/qwhoyvluk-u.md
new file mode 100644
index 00000000..da62c625
--- /dev/null
+++ b/src/content/videos/pythonvigo/qwhoyvluk-u.md
@@ -0,0 +1,11 @@
+---
+sourceId: 'qWHoyvLUK-U'
+groupId: 'pythonvigo'
+groupName: 'PythonVigo'
+groupLogo: 'https://vigotech.org/images/python_vigo.png'
+title: 'Mi primera metaclase: un ejemplo práctico - Miguel González Álvarez - PyDay'
+player: 'youtube'
+url: 'https://www.youtube.com/watch?v=qWHoyvLUK-U'
+publishedAt: null
+thumbnail: 'https://i.ytimg.com/vi/qWHoyvLUK-U/hqdefault.jpg?sqp=-oaymwE2CNACELwBSFXyq4qpAygIARUAAIhCGAFwAcABBvABAfgB_giAAtAFigIMCAAQARhlIGUoZTAP&rs=AOn4CLA-KKa6yEQ7XnjyXHOuXw1ZSjlspQ'
+---
diff --git a/src/content/videos/pythonvigo/rodhalbfano.md b/src/content/videos/pythonvigo/rodhalbfano.md
new file mode 100644
index 00000000..7ead7ee9
--- /dev/null
+++ b/src/content/videos/pythonvigo/rodhalbfano.md
@@ -0,0 +1,11 @@
+---
+sourceId: 'RODHAlBFANo'
+groupId: 'pythonvigo'
+groupName: 'PythonVigo'
+groupLogo: 'https://vigotech.org/images/python_vigo.png'
+title: 'Great balls of fire (Visualizando datos con Dash), por Iván Nieto'
+player: 'youtube'
+url: 'https://www.youtube.com/watch?v=RODHAlBFANo'
+publishedAt: null
+thumbnail: 'https://i.ytimg.com/vi/RODHAlBFANo/hqdefault.jpg?sqp=-oaymwEcCNACELwBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==&rs=AOn4CLDrEiM_29V220bW-s0kb527BPR-Vg'
+---
diff --git a/src/content/videos/pythonvigo/sy233urmikm.md b/src/content/videos/pythonvigo/sy233urmikm.md
new file mode 100644
index 00000000..b13bd4ae
--- /dev/null
+++ b/src/content/videos/pythonvigo/sy233urmikm.md
@@ -0,0 +1,11 @@
+---
+sourceId: 'sy233UrMikM'
+groupId: 'pythonvigo'
+groupName: 'PythonVigo'
+groupLogo: 'https://vigotech.org/images/python_vigo.png'
+title: 'Luis Rovirosa - Learned lessons in a real world project'
+player: 'youtube'
+url: 'https://www.youtube.com/watch?v=sy233UrMikM'
+publishedAt: 1517562159000
+thumbnail: 'https://i.ytimg.com/vi/sy233UrMikM/hqdefault.jpg'
+---
diff --git a/src/content/videos/pythonvigo/t1wih6hs-yw.md b/src/content/videos/pythonvigo/t1wih6hs-yw.md
new file mode 100644
index 00000000..f3066c73
--- /dev/null
+++ b/src/content/videos/pythonvigo/t1wih6hs-yw.md
@@ -0,0 +1,11 @@
+---
+sourceId: 'T1wih6Hs-Yw'
+groupId: 'pythonvigo'
+groupName: 'PythonVigo'
+groupLogo: 'https://vigotech.org/images/python_vigo.png'
+title: 'Brujería con Numpy.einsum, por David de la Iglesia'
+player: 'youtube'
+url: 'https://www.youtube.com/watch?v=T1wih6Hs-Yw'
+publishedAt: null
+thumbnail: 'https://i.ytimg.com/vi/T1wih6Hs-Yw/hqdefault.jpg?sqp=-oaymwEcCNACELwBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==&rs=AOn4CLDOR_hvVlirsyQJzULPI4XAveyRbw'
+---
diff --git a/src/content/videos/pythonvigo/v-ctyi8ooli.md b/src/content/videos/pythonvigo/v-ctyi8ooli.md
new file mode 100644
index 00000000..22d07baa
--- /dev/null
+++ b/src/content/videos/pythonvigo/v-ctyi8ooli.md
@@ -0,0 +1,11 @@
+---
+sourceId: 'V-cTyi8oOLI'
+groupId: 'pythonvigo'
+groupName: 'PythonVigo'
+groupLogo: 'https://vigotech.org/images/python_vigo.png'
+title: 'Emisión en directo de Python Vigo'
+player: 'youtube'
+url: 'https://www.youtube.com/watch?v=V-cTyi8oOLI'
+publishedAt: 1705320138000
+thumbnail: 'https://i.ytimg.com/vi/V-cTyi8oOLI/hqdefault.jpg'
+---
diff --git a/src/content/videos/pythonvigo/wrl5h0tmq-w.md b/src/content/videos/pythonvigo/wrl5h0tmq-w.md
new file mode 100644
index 00000000..57a151cd
--- /dev/null
+++ b/src/content/videos/pythonvigo/wrl5h0tmq-w.md
@@ -0,0 +1,11 @@
+---
+sourceId: 'WrL5H0Tmq-w'
+groupId: 'pythonvigo'
+groupName: 'PythonVigo'
+groupLogo: 'https://vigotech.org/images/python_vigo.png'
+title: 'APIS de Machine Learning: como usarlas desde Python. Por David de la Iglesia.'
+player: 'youtube'
+url: 'https://www.youtube.com/watch?v=WrL5H0Tmq-w'
+publishedAt: null
+thumbnail: 'https://i.ytimg.com/vi/WrL5H0Tmq-w/hqdefault.jpg?sqp=-oaymwEcCNACELwBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==&rs=AOn4CLCJ5MMw-7UgYp4dnRy47EOwbjj8uQ'
+---
diff --git a/src/content/videos/pythonvigo/xn98drgum7s.md b/src/content/videos/pythonvigo/xn98drgum7s.md
new file mode 100644
index 00000000..71b8f2eb
--- /dev/null
+++ b/src/content/videos/pythonvigo/xn98drgum7s.md
@@ -0,0 +1,11 @@
+---
+sourceId: 'XN98drGum7s'
+groupId: 'pythonvigo'
+groupName: 'PythonVigo'
+groupLogo: 'https://vigotech.org/images/python_vigo.png'
+title: 'Calling to the future - Eloy Coto - PyDay Galicia'
+player: 'youtube'
+url: 'https://www.youtube.com/watch?v=XN98drGum7s'
+publishedAt: null
+thumbnail: 'https://i.ytimg.com/vi/XN98drGum7s/hqdefault.jpg?sqp=-oaymwE2CNACELwBSFXyq4qpAygIARUAAIhCGAFwAcABBvABAfgB_giAAtAFigIMCAAQARg7IGUoOTAP&rs=AOn4CLCgFUFZhRbyGDTI4256aocgQx5v4w'
+---
diff --git a/src/content/videos/pythonvigo/y-w9t8kwnz4.md b/src/content/videos/pythonvigo/y-w9t8kwnz4.md
new file mode 100644
index 00000000..b595d8d0
--- /dev/null
+++ b/src/content/videos/pythonvigo/y-w9t8kwnz4.md
@@ -0,0 +1,11 @@
+---
+sourceId: 'Y-W9t8KWNz4'
+groupId: 'pythonvigo'
+groupName: 'PythonVigo'
+groupLogo: 'https://vigotech.org/images/python_vigo.png'
+title: 'This summer master the mosquittos, por Alex Hermida'
+player: 'youtube'
+url: 'https://www.youtube.com/watch?v=Y-W9t8KWNz4'
+publishedAt: null
+thumbnail: 'https://i.ytimg.com/vi/Y-W9t8KWNz4/hqdefault.jpg?sqp=-oaymwEcCNACELwBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==&rs=AOn4CLBFsJEgD2WDyKes3FoXSRhDJo5KdQ'
+---
diff --git a/src/content/videos/pythonvigo/yqzx2m7ay.md b/src/content/videos/pythonvigo/yqzx2m7ay.md
new file mode 100644
index 00000000..180ce059
--- /dev/null
+++ b/src/content/videos/pythonvigo/yqzx2m7ay.md
@@ -0,0 +1,11 @@
+---
+sourceId: '-_Yqzx2M7AY'
+groupId: 'pythonvigo'
+groupName: 'PythonVigo'
+groupLogo: 'https://vigotech.org/images/python_vigo.png'
+title: 'Creando tu propio simulador cuántico en 200 líneas por Ismael Faro'
+player: 'youtube'
+url: 'https://www.youtube.com/watch?v=-_Yqzx2M7AY'
+publishedAt: 1594968873000
+thumbnail: 'https://i.ytimg.com/vi/-_Yqzx2M7AY/hqdefault.jpg'
+---
diff --git a/src/content/videos/pythonvigo/z-azc6hkzk8.md b/src/content/videos/pythonvigo/z-azc6hkzk8.md
new file mode 100644
index 00000000..3b60914a
--- /dev/null
+++ b/src/content/videos/pythonvigo/z-azc6hkzk8.md
@@ -0,0 +1,11 @@
+---
+sourceId: 'Z_AzC6HkZk8'
+groupId: 'pythonvigo'
+groupName: 'PythonVigo'
+groupLogo: 'https://vigotech.org/images/python_vigo.png'
+title: 'Emisión en directo Python Vigo'
+player: 'youtube'
+url: 'https://www.youtube.com/watch?v=Z_AzC6HkZk8'
+publishedAt: null
+thumbnail: 'https://i.ytimg.com/vi/Z_AzC6HkZk8/hqdefault.jpg?sqp=-oaymwEcCNACELwBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==&rs=AOn4CLAKAw9OJzMaQ982P5PFatKiK1Mxkg'
+---
diff --git a/src/content/videos/vigojug/4vdhl-s-fga.md b/src/content/videos/vigojug/4vdhl-s-fga.md
new file mode 100644
index 00000000..aab3bd92
--- /dev/null
+++ b/src/content/videos/vigojug/4vdhl-s-fga.md
@@ -0,0 +1,11 @@
+---
+sourceId: '4vDhL_S_FGA'
+groupId: 'vigojug'
+groupName: 'VigoJUG'
+groupLogo: 'https://vigotech.org/images/vigojug.jpg'
+title: 'Laretas AMA: Cristina Vázquez'
+player: 'youtube'
+url: 'https://www.youtube.com/watch?v=4vDhL_S_FGA'
+publishedAt: 1624004163000
+thumbnail: 'https://i.ytimg.com/vi/4vDhL_S_FGA/hqdefault.jpg'
+---
diff --git a/src/content/videos/vigojug/4wltqdk0asm.md b/src/content/videos/vigojug/4wltqdk0asm.md
new file mode 100644
index 00000000..98fa67b3
--- /dev/null
+++ b/src/content/videos/vigojug/4wltqdk0asm.md
@@ -0,0 +1,11 @@
+---
+sourceId: '4WlTqDk0ASM'
+groupId: 'vigojug'
+groupName: 'VigoJUG'
+groupLogo: 'https://vigotech.org/images/vigojug.jpg'
+title: 'Laretas AMA: Agustín Tourón'
+player: 'youtube'
+url: 'https://www.youtube.com/watch?v=4WlTqDk0ASM'
+publishedAt: 1631174511000
+thumbnail: 'https://i.ytimg.com/vi/4WlTqDk0ASM/hqdefault.jpg'
+---
diff --git a/src/content/videos/vigojug/4yvsszmhtzo.md b/src/content/videos/vigojug/4yvsszmhtzo.md
new file mode 100644
index 00000000..ca3381da
--- /dev/null
+++ b/src/content/videos/vigojug/4yvsszmhtzo.md
@@ -0,0 +1,11 @@
+---
+sourceId: '4yvSSZMHTZo'
+groupId: 'vigojug'
+groupName: 'VigoJUG'
+groupLogo: 'https://vigotech.org/images/vigojug.jpg'
+title: 'Reactive programming con RxJava'
+player: 'youtube'
+url: 'https://www.youtube.com/watch?v=4yvSSZMHTZo'
+publishedAt: 1493755039000
+thumbnail: 'https://i.ytimg.com/vi/4yvSSZMHTZo/hqdefault.jpg'
+---
diff --git a/src/content/videos/vigojug/5braph5bypy.md b/src/content/videos/vigojug/5braph5bypy.md
new file mode 100644
index 00000000..b78a737c
--- /dev/null
+++ b/src/content/videos/vigojug/5braph5bypy.md
@@ -0,0 +1,11 @@
+---
+sourceId: '5BRaPH5BYPY'
+groupId: 'vigojug'
+groupName: 'VigoJUG'
+groupLogo: 'https://vigotech.org/images/vigojug.jpg'
+title: 'Laretas Geek - Octubre 2020 - Especial desarrollo web con Adalab'
+player: 'youtube'
+url: 'https://www.youtube.com/watch?v=5BRaPH5BYPY'
+publishedAt: null
+thumbnail: 'https://i.ytimg.com/vi/5BRaPH5BYPY/hqdefault.jpg?sqp=-oaymwEcCNACELwBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==&rs=AOn4CLCwgNtsuvu37TXriEGja1wIS2r0kA'
+---
diff --git a/src/content/videos/vigojug/7aiu-wlhlgk.md b/src/content/videos/vigojug/7aiu-wlhlgk.md
new file mode 100644
index 00000000..2216c42a
--- /dev/null
+++ b/src/content/videos/vigojug/7aiu-wlhlgk.md
@@ -0,0 +1,11 @@
+---
+sourceId: '7AiU-Wlhlgk'
+groupId: 'vigojug'
+groupName: 'VigoJUG'
+groupLogo: 'https://vigotech.org/images/vigojug.jpg'
+title: 'Laretas AMA: Fran Puga'
+player: 'youtube'
+url: 'https://www.youtube.com/watch?v=7AiU-Wlhlgk'
+publishedAt: 1619251491000
+thumbnail: 'https://i.ytimg.com/vi/7AiU-Wlhlgk/hqdefault.jpg'
+---
diff --git a/src/content/videos/vigojug/7q-t-tbupcs.md b/src/content/videos/vigojug/7q-t-tbupcs.md
new file mode 100644
index 00000000..139652ea
--- /dev/null
+++ b/src/content/videos/vigojug/7q-t-tbupcs.md
@@ -0,0 +1,11 @@
+---
+sourceId: '7Q-t_TbUPCs'
+groupId: 'vigojug'
+groupName: 'VigoJUG'
+groupLogo: 'https://vigotech.org/images/vigojug.jpg'
+title: 'Laretas Geek - Marzo 2021 - especial Extreme Programming'
+player: 'youtube'
+url: 'https://www.youtube.com/watch?v=7Q-t_TbUPCs'
+publishedAt: null
+thumbnail: 'https://i.ytimg.com/vi/7Q-t_TbUPCs/hqdefault.jpg?sqp=-oaymwEcCNACELwBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==&rs=AOn4CLDqsTvgIBAlkgmTSoORec0gEq0ZCQ'
+---
diff --git a/src/content/videos/vigojug/8643werug-s.md b/src/content/videos/vigojug/8643werug-s.md
new file mode 100644
index 00000000..4cd9a5f5
--- /dev/null
+++ b/src/content/videos/vigojug/8643werug-s.md
@@ -0,0 +1,11 @@
+---
+sourceId: '8643WerUG-s'
+groupId: 'vigojug'
+groupName: 'VigoJUG'
+groupLogo: 'https://vigotech.org/images/vigojug.jpg'
+title: 'O cuarto meetup do VigoJUG: Kotlin, o Java para o século XXI'
+player: 'youtube'
+url: 'https://www.youtube.com/watch?v=8643WerUG-s'
+publishedAt: 1507016769000
+thumbnail: 'https://i.ytimg.com/vi/8643WerUG-s/hqdefault.jpg'
+---
diff --git a/src/content/videos/vigojug/9-zms-8-01a.md b/src/content/videos/vigojug/9-zms-8-01a.md
new file mode 100644
index 00000000..a7c6b775
--- /dev/null
+++ b/src/content/videos/vigojug/9-zms-8-01a.md
@@ -0,0 +1,11 @@
+---
+sourceId: '9_zMs-8-01A'
+groupId: 'vigojug'
+groupName: 'VigoJUG'
+groupLogo: 'https://vigotech.org/images/vigojug.jpg'
+title: 'Laretas AMA: André Maneiro'
+player: 'youtube'
+url: 'https://www.youtube.com/watch?v=9_zMs-8-01A'
+publishedAt: 1620375037000
+thumbnail: 'https://i.ytimg.com/vi/9_zMs-8-01A/hqdefault.jpg'
+---
diff --git a/src/content/videos/vigojug/ajkifnwjug0.md b/src/content/videos/vigojug/ajkifnwjug0.md
new file mode 100644
index 00000000..5cf5bbda
--- /dev/null
+++ b/src/content/videos/vigojug/ajkifnwjug0.md
@@ -0,0 +1,11 @@
+---
+sourceId: 'aJkifnWjug0'
+groupId: 'vigojug'
+groupName: 'VigoJUG'
+groupLogo: 'https://vigotech.org/images/vigojug.jpg'
+title: 'Laretas AMA: Alberto Ruibal'
+player: 'youtube'
+url: 'https://www.youtube.com/watch?v=aJkifnWjug0'
+publishedAt: 1617955769000
+thumbnail: 'https://i.ytimg.com/vi/aJkifnWjug0/hqdefault.jpg'
+---
diff --git a/src/content/videos/vigojug/d-k35eeivca.md b/src/content/videos/vigojug/d-k35eeivca.md
new file mode 100644
index 00000000..acf4a7ad
--- /dev/null
+++ b/src/content/videos/vigojug/d-k35eeivca.md
@@ -0,0 +1,11 @@
+---
+sourceId: 'd-K35EeIvcA'
+groupId: 'vigojug'
+groupName: 'VigoJUG'
+groupLogo: 'https://vigotech.org/images/vigojug.jpg'
+title: 'Laretas Geek - Enero 2021 - Especial Elastic'
+player: 'youtube'
+url: 'https://www.youtube.com/watch?v=d-K35EeIvcA'
+publishedAt: null
+thumbnail: 'https://i.ytimg.com/vi/d-K35EeIvcA/hqdefault.jpg?sqp=-oaymwEcCNACELwBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==&rs=AOn4CLCowkGr158d9UZ0jhGNdCs5usqNMg'
+---
diff --git a/src/content/videos/vigojug/ftsdoh5g2nm.md b/src/content/videos/vigojug/ftsdoh5g2nm.md
new file mode 100644
index 00000000..06ed7146
--- /dev/null
+++ b/src/content/videos/vigojug/ftsdoh5g2nm.md
@@ -0,0 +1,11 @@
+---
+sourceId: 'FTsDoh5G2nM'
+groupId: 'vigojug'
+groupName: 'VigoJUG'
+groupLogo: 'https://vigotech.org/images/vigojug.jpg'
+title: 'JReleaser - Liberando a la velocidad de la luz'
+player: 'youtube'
+url: 'https://www.youtube.com/watch?v=FTsDoh5G2nM'
+publishedAt: 1625211411000
+thumbnail: 'https://i.ytimg.com/vi/FTsDoh5G2nM/hqdefault.jpg'
+---
diff --git a/src/content/videos/vigojug/fx1fzzphavu.md b/src/content/videos/vigojug/fx1fzzphavu.md
new file mode 100644
index 00000000..ff1f81d8
--- /dev/null
+++ b/src/content/videos/vigojug/fx1fzzphavu.md
@@ -0,0 +1,11 @@
+---
+sourceId: 'fX1fzZPHaVU'
+groupId: 'vigojug'
+groupName: 'VigoJUG'
+groupLogo: 'https://vigotech.org/images/vigojug.jpg'
+title: 'O sexto meetup do VigoJUG: "In-Memory Datagrid en arquitecturas de tiempo real"'
+player: 'youtube'
+url: 'https://www.youtube.com/watch?v=fX1fzZPHaVU'
+publishedAt: 1507057333000
+thumbnail: 'https://i.ytimg.com/vi/fX1fzZPHaVU/hqdefault.jpg'
+---
diff --git a/src/content/videos/vigojug/gqrj-vh7mr8.md b/src/content/videos/vigojug/gqrj-vh7mr8.md
new file mode 100644
index 00000000..89e6387e
--- /dev/null
+++ b/src/content/videos/vigojug/gqrj-vh7mr8.md
@@ -0,0 +1,11 @@
+---
+sourceId: 'gqrj-VH7mR8'
+groupId: 'vigojug'
+groupName: 'VigoJUG'
+groupLogo: 'https://vigotech.org/images/vigojug.jpg'
+title: 'Laretas AMA: Fernando Prieto'
+player: 'youtube'
+url: 'https://www.youtube.com/watch?v=gqrj-VH7mR8'
+publishedAt: 1627027803000
+thumbnail: 'https://i.ytimg.com/vi/gqrj-VH7mR8/hqdefault.jpg'
+---
diff --git a/src/content/videos/vigojug/jl7pegkda4s.md b/src/content/videos/vigojug/jl7pegkda4s.md
new file mode 100644
index 00000000..4704749c
--- /dev/null
+++ b/src/content/videos/vigojug/jl7pegkda4s.md
@@ -0,0 +1,11 @@
+---
+sourceId: 'JL7pEGKda4s'
+groupId: 'vigojug'
+groupName: 'VigoJUG'
+groupLogo: 'https://vigotech.org/images/vigojug.jpg'
+title: 'Laretas AMA: Abdón Rodríguez'
+player: 'youtube'
+url: 'https://www.youtube.com/watch?v=JL7pEGKda4s'
+publishedAt: null
+thumbnail: 'https://i.ytimg.com/vi/JL7pEGKda4s/hqdefault.jpg?sqp=-oaymwEcCNACELwBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==&rs=AOn4CLDGGMW6OBepdec6NwHuAtqUSAFFQQ'
+---
diff --git a/src/content/videos/vigojug/jokts-f4pts.md b/src/content/videos/vigojug/jokts-f4pts.md
new file mode 100644
index 00000000..09365baa
--- /dev/null
+++ b/src/content/videos/vigojug/jokts-f4pts.md
@@ -0,0 +1,11 @@
+---
+sourceId: 'JoKTs_F4PTs'
+groupId: 'vigojug'
+groupName: 'VigoJUG'
+groupLogo: 'https://vigotech.org/images/vigojug.jpg'
+title: 'LaretasGeek - Marzo 2021 - Especial Java 16'
+player: 'youtube'
+url: 'https://www.youtube.com/watch?v=JoKTs_F4PTs'
+publishedAt: 1619771846000
+thumbnail: 'https://i.ytimg.com/vi/JoKTs_F4PTs/hqdefault.jpg'
+---
diff --git a/src/content/videos/vigojug/jvfig1ukawc.md b/src/content/videos/vigojug/jvfig1ukawc.md
new file mode 100644
index 00000000..4a41d8f8
--- /dev/null
+++ b/src/content/videos/vigojug/jvfig1ukawc.md
@@ -0,0 +1,11 @@
+---
+sourceId: 'jvFiG1ukAWc'
+groupId: 'vigojug'
+groupName: 'VigoJUG'
+groupLogo: 'https://vigotech.org/images/vigojug.jpg'
+title: 'Laretas AMA: Antón Román'
+player: 'youtube'
+url: 'https://www.youtube.com/watch?v=jvFiG1ukAWc'
+publishedAt: 1618560349000
+thumbnail: 'https://i.ytimg.com/vi/jvFiG1ukAWc/hqdefault.jpg'
+---
diff --git a/src/content/videos/vigojug/k6s9w8iton0.md b/src/content/videos/vigojug/k6s9w8iton0.md
new file mode 100644
index 00000000..814e4a23
--- /dev/null
+++ b/src/content/videos/vigojug/k6s9w8iton0.md
@@ -0,0 +1,11 @@
+---
+sourceId: 'K6S9w8iton0'
+groupId: 'vigojug'
+groupName: 'VigoJUG'
+groupLogo: 'https://vigotech.org/images/vigojug.jpg'
+title: 'Laretas AMA: Pilar Vila'
+player: 'youtube'
+url: 'https://www.youtube.com/watch?v=K6S9w8iton0'
+publishedAt: 1622880548000
+thumbnail: 'https://i.ytimg.com/vi/K6S9w8iton0/hqdefault.jpg'
+---
diff --git a/src/content/videos/vigojug/khdve9foa-u.md b/src/content/videos/vigojug/khdve9foa-u.md
new file mode 100644
index 00000000..3c948ffe
--- /dev/null
+++ b/src/content/videos/vigojug/khdve9foa-u.md
@@ -0,0 +1,11 @@
+---
+sourceId: 'KHdVe9fOa-U'
+groupId: 'vigojug'
+groupName: 'VigoJUG'
+groupLogo: 'https://vigotech.org/images/vigojug.jpg'
+title: 'Introducción de Cassandra con Java'
+player: 'youtube'
+url: 'https://www.youtube.com/watch?v=KHdVe9fOa-U'
+publishedAt: 1493754951000
+thumbnail: 'https://i.ytimg.com/vi/KHdVe9fOa-U/hqdefault.jpg'
+---
diff --git a/src/content/videos/vigojug/km9yicqhtps.md b/src/content/videos/vigojug/km9yicqhtps.md
new file mode 100644
index 00000000..8ecc8979
--- /dev/null
+++ b/src/content/videos/vigojug/km9yicqhtps.md
@@ -0,0 +1,11 @@
+---
+sourceId: 'km9YiCqhtps'
+groupId: 'vigojug'
+groupName: 'VigoJUG'
+groupLogo: 'https://vigotech.org/images/vigojug.jpg'
+title: 'Laretas AMA: Eloy Coto'
+player: 'youtube'
+url: 'https://www.youtube.com/watch?v=km9YiCqhtps'
+publishedAt: 1617350713000
+thumbnail: 'https://i.ytimg.com/vi/km9YiCqhtps/hqdefault.jpg'
+---
diff --git a/src/content/videos/vigojug/l25ryirmtyq.md b/src/content/videos/vigojug/l25ryirmtyq.md
new file mode 100644
index 00000000..6a77ea5f
--- /dev/null
+++ b/src/content/videos/vigojug/l25ryirmtyq.md
@@ -0,0 +1,11 @@
+---
+sourceId: 'L25ryiRmTYQ'
+groupId: 'vigojug'
+groupName: 'VigoJUG'
+groupLogo: 'https://vigotech.org/images/vigojug.jpg'
+title: 'Laretas Geek - Septiembre 2020 - Especial Apache Kafka'
+player: 'youtube'
+url: 'https://www.youtube.com/watch?v=L25ryiRmTYQ'
+publishedAt: null
+thumbnail: 'https://i.ytimg.com/vi/L25ryiRmTYQ/hqdefault.jpg?sqp=-oaymwEcCNACELwBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==&rs=AOn4CLAjVkLSNcgqUAMLHqjDBBWW6kAqew'
+---
diff --git a/src/content/videos/vigojug/mewdxxkjgsy.md b/src/content/videos/vigojug/mewdxxkjgsy.md
new file mode 100644
index 00000000..8e570b06
--- /dev/null
+++ b/src/content/videos/vigojug/mewdxxkjgsy.md
@@ -0,0 +1,11 @@
+---
+sourceId: 'MewdxXkjgsY'
+groupId: 'vigojug'
+groupName: 'VigoJUG'
+groupLogo: 'https://vigotech.org/images/vigojug.jpg'
+title: 'Laretas Geek - Diciembre 2020 - Especial Java Champions'
+player: 'youtube'
+url: 'https://www.youtube.com/watch?v=MewdxXkjgsY'
+publishedAt: null
+thumbnail: 'https://i.ytimg.com/vi/MewdxXkjgsY/hqdefault.jpg?sqp=-oaymwEcCNACELwBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==&rs=AOn4CLCjNppF3v1MxoA9hybZIaYirzFDDA'
+---
diff --git a/src/content/videos/vigojug/mtcimjbfej0.md b/src/content/videos/vigojug/mtcimjbfej0.md
new file mode 100644
index 00000000..e6698543
--- /dev/null
+++ b/src/content/videos/vigojug/mtcimjbfej0.md
@@ -0,0 +1,11 @@
+---
+sourceId: 'MtcImjBFEj0'
+groupId: 'vigojug'
+groupName: 'VigoJUG'
+groupLogo: 'https://vigotech.org/images/vigojug.jpg'
+title: 'Laretas Geek - Junio 2020 - Mesa redonda 25 años de Java'
+player: 'youtube'
+url: 'https://www.youtube.com/watch?v=MtcImjBFEj0'
+publishedAt: null
+thumbnail: 'https://i.ytimg.com/vi/MtcImjBFEj0/hqdefault.jpg?sqp=-oaymwEcCNACELwBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==&rs=AOn4CLCeVKhRaoxSDDhvydu04SPnoA49iA'
+---
diff --git a/src/content/videos/vigojug/nvhjthobq5i.md b/src/content/videos/vigojug/nvhjthobq5i.md
new file mode 100644
index 00000000..b04cdb97
--- /dev/null
+++ b/src/content/videos/vigojug/nvhjthobq5i.md
@@ -0,0 +1,11 @@
+---
+sourceId: 'nvHJthOBQ5I'
+groupId: 'vigojug'
+groupName: 'VigoJUG'
+groupLogo: 'https://vigotech.org/images/vigojug.jpg'
+title: 'LaretasGeek - Febrero 2021 - Especial Developer Experience'
+player: 'youtube'
+url: 'https://www.youtube.com/watch?v=nvHJthOBQ5I'
+publishedAt: null
+thumbnail: 'https://i.ytimg.com/vi/nvHJthOBQ5I/hqdefault.jpg?sqp=-oaymwEcCNACELwBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==&rs=AOn4CLDDvfCCgB_6w4G72VCOw6ZyxRII-A'
+---
diff --git a/src/content/videos/vigojug/pkqtlj38x7m.md b/src/content/videos/vigojug/pkqtlj38x7m.md
new file mode 100644
index 00000000..0208c70f
--- /dev/null
+++ b/src/content/videos/vigojug/pkqtlj38x7m.md
@@ -0,0 +1,11 @@
+---
+sourceId: 'PKqTlj38X7M'
+groupId: 'vigojug'
+groupName: 'VigoJUG'
+groupLogo: 'https://vigotech.org/images/vigojug.jpg'
+title: 'Make Java Great Again! por @tomasalmeida de Netcentric. 30 min.'
+player: 'youtube'
+url: 'https://www.youtube.com/watch?v=PKqTlj38X7M'
+publishedAt: 1490818476000
+thumbnail: 'https://i.ytimg.com/vi/PKqTlj38X7M/hqdefault.jpg'
+---
diff --git a/src/content/videos/vigojug/plsc3jnbx5o.md b/src/content/videos/vigojug/plsc3jnbx5o.md
new file mode 100644
index 00000000..c4616c07
--- /dev/null
+++ b/src/content/videos/vigojug/plsc3jnbx5o.md
@@ -0,0 +1,11 @@
+---
+sourceId: 'pLsC3jnbX5o'
+groupId: 'vigojug'
+groupName: 'VigoJUG'
+groupLogo: 'https://vigotech.org/images/vigojug.jpg'
+title: 'Emisión en directo de Vigo JUG'
+player: 'youtube'
+url: 'https://www.youtube.com/watch?v=pLsC3jnbX5o'
+publishedAt: 1490819092000
+thumbnail: 'https://i.ytimg.com/vi/pLsC3jnbX5o/hqdefault.jpg'
+---
diff --git a/src/content/videos/vigojug/se0ov3v11mm.md b/src/content/videos/vigojug/se0ov3v11mm.md
new file mode 100644
index 00000000..81d32e48
--- /dev/null
+++ b/src/content/videos/vigojug/se0ov3v11mm.md
@@ -0,0 +1,11 @@
+---
+sourceId: 'Se0Ov3V11MM'
+groupId: 'vigojug'
+groupName: 'VigoJUG'
+groupLogo: 'https://vigotech.org/images/vigojug.jpg'
+title: 'O sétimo meetup do VigoJUG: Desarrollo de microservicios con Spring Boot'
+player: 'youtube'
+url: 'https://www.youtube.com/watch?v=Se0Ov3V11MM'
+publishedAt: 1513409471000
+thumbnail: 'https://i.ytimg.com/vi/Se0Ov3V11MM/hqdefault.jpg'
+---
diff --git a/src/content/videos/vigojug/shw-mdfmqfa.md b/src/content/videos/vigojug/shw-mdfmqfa.md
new file mode 100644
index 00000000..45e2fb26
--- /dev/null
+++ b/src/content/videos/vigojug/shw-mdfmqfa.md
@@ -0,0 +1,11 @@
+---
+sourceId: 'SHw_MdfmqfA'
+groupId: 'vigojug'
+groupName: 'VigoJUG'
+groupLogo: 'https://vigotech.org/images/vigojug.jpg'
+title: 'Laretas Geek - Agosto 2020 - Especial Comunidades Galicia'
+player: 'youtube'
+url: 'https://www.youtube.com/watch?v=SHw_MdfmqfA'
+publishedAt: null
+thumbnail: 'https://i.ytimg.com/vi/SHw_MdfmqfA/hqdefault.jpg?sqp=-oaymwEcCNACELwBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==&rs=AOn4CLBSv3uSQLAsQ688rabYh22lk11whg'
+---
diff --git a/src/content/videos/vigojug/smg2p6esvnc.md b/src/content/videos/vigojug/smg2p6esvnc.md
new file mode 100644
index 00000000..9d9be3eb
--- /dev/null
+++ b/src/content/videos/vigojug/smg2p6esvnc.md
@@ -0,0 +1,11 @@
+---
+sourceId: 'smG2P6Esvnc'
+groupId: 'vigojug'
+groupName: 'VigoJUG'
+groupLogo: 'https://vigotech.org/images/vigojug.jpg'
+title: '"De Groovy... e Sancho Panza" por Antón Rodríguez de Optare Solutions 30 min.'
+player: 'youtube'
+url: 'https://www.youtube.com/watch?v=smG2P6Esvnc'
+publishedAt: 1490818577000
+thumbnail: 'https://i.ytimg.com/vi/smG2P6Esvnc/hqdefault.jpg'
+---
diff --git a/src/content/videos/vigojug/tx-ji5ftxpq.md b/src/content/videos/vigojug/tx-ji5ftxpq.md
new file mode 100644
index 00000000..9bce4f3e
--- /dev/null
+++ b/src/content/videos/vigojug/tx-ji5ftxpq.md
@@ -0,0 +1,11 @@
+---
+sourceId: 'tx_ji5FTXPQ'
+groupId: 'vigojug'
+groupName: 'VigoJUG'
+groupLogo: 'https://vigotech.org/images/vigojug.jpg'
+title: 'Laretas AMA: Luz Castro'
+player: 'youtube'
+url: 'https://www.youtube.com/watch?v=tx_ji5FTXPQ'
+publishedAt: 1621670994000
+thumbnail: 'https://i.ytimg.com/vi/tx_ji5FTXPQ/hqdefault.jpg'
+---
diff --git a/src/content/videos/vigojug/vyo-e3a9hlg.md b/src/content/videos/vigojug/vyo-e3a9hlg.md
new file mode 100644
index 00000000..c047026d
--- /dev/null
+++ b/src/content/videos/vigojug/vyo-e3a9hlg.md
@@ -0,0 +1,11 @@
+---
+sourceId: 'vYO-e3A9hlg'
+groupId: 'vigojug'
+groupName: 'VigoJUG'
+groupLogo: 'https://vigotech.org/images/vigojug.jpg'
+title: 'Laretas AMA: David García'
+player: 'youtube'
+url: 'https://www.youtube.com/watch?v=vYO-e3A9hlg'
+publishedAt: null
+thumbnail: 'https://i.ytimg.com/vi/vYO-e3A9hlg/hqdefault.jpg?sqp=-oaymwEcCNACELwBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==&rs=AOn4CLC035QMMxdGVMkK-9KQW-ITbXgOVA'
+---
diff --git a/src/content/videos/vigojug/w-kkwegct0.md b/src/content/videos/vigojug/w-kkwegct0.md
new file mode 100644
index 00000000..1893f595
--- /dev/null
+++ b/src/content/videos/vigojug/w-kkwegct0.md
@@ -0,0 +1,11 @@
+---
+sourceId: '_w_kKWeGct0'
+groupId: 'vigojug'
+groupName: 'VigoJUG'
+groupLogo: 'https://vigotech.org/images/vigojug.jpg'
+title: 'Quarkus World Tour 2021: VigoJUG & CoruñaJUG'
+player: 'youtube'
+url: 'https://www.youtube.com/watch?v=_w_kKWeGct0'
+publishedAt: null
+thumbnail: 'https://i.ytimg.com/vi/_w_kKWeGct0/hqdefault.jpg?sqp=-oaymwEcCNACELwBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==&rs=AOn4CLBFpudfE6cvfbjFFqzWSBiBn-0Z1g'
+---
diff --git a/src/content/videos/vigojug/wheiaflsayw.md b/src/content/videos/vigojug/wheiaflsayw.md
new file mode 100644
index 00000000..2ceabb17
--- /dev/null
+++ b/src/content/videos/vigojug/wheiaflsayw.md
@@ -0,0 +1,11 @@
+---
+sourceId: 'WHeIAfLsAyw'
+groupId: 'vigojug'
+groupName: 'VigoJUG'
+groupLogo: 'https://vigotech.org/images/vigojug.jpg'
+title: 'Laretas AMA: Miguel Camba'
+player: 'youtube'
+url: 'https://www.youtube.com/watch?v=WHeIAfLsAyw'
+publishedAt: 1625731749000
+thumbnail: 'https://i.ytimg.com/vi/WHeIAfLsAyw/hqdefault.jpg'
+---
diff --git a/src/content/videos/vigojug/xe4q7ocbxy8.md b/src/content/videos/vigojug/xe4q7ocbxy8.md
new file mode 100644
index 00000000..d9d05a8e
--- /dev/null
+++ b/src/content/videos/vigojug/xe4q7ocbxy8.md
@@ -0,0 +1,11 @@
+---
+sourceId: 'XE4q7OCBXy8'
+groupId: 'vigojug'
+groupName: 'VigoJUG'
+groupLogo: 'https://vigotech.org/images/vigojug.jpg'
+title: 'Laretas AMA: Telmo Pérez'
+player: 'youtube'
+url: 'https://www.youtube.com/watch?v=XE4q7OCBXy8'
+publishedAt: 1633075094000
+thumbnail: 'https://i.ytimg.com/vi/XE4q7OCBXy8/hqdefault.jpg'
+---
diff --git a/src/content/videos/vigojug/xyztcy5wqnc.md b/src/content/videos/vigojug/xyztcy5wqnc.md
new file mode 100644
index 00000000..64c18331
--- /dev/null
+++ b/src/content/videos/vigojug/xyztcy5wqnc.md
@@ -0,0 +1,11 @@
+---
+sourceId: 'XyZTCy5WQNc'
+groupId: 'vigojug'
+groupName: 'VigoJUG'
+groupLogo: 'https://vigotech.org/images/vigojug.jpg'
+title: 'Laretas Geek - Julio 2020 - Especial Engineering Management'
+player: 'youtube'
+url: 'https://www.youtube.com/watch?v=XyZTCy5WQNc'
+publishedAt: null
+thumbnail: 'https://i.ytimg.com/vi/XyZTCy5WQNc/hqdefault.jpg?sqp=-oaymwEcCNACELwBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==&rs=AOn4CLA5oaApvgzD8pVCgh4EEmGD3l60Ww'
+---
diff --git a/src/content/videos/vigojug/z-4up8hzjlq.md b/src/content/videos/vigojug/z-4up8hzjlq.md
new file mode 100644
index 00000000..a1b0206d
--- /dev/null
+++ b/src/content/videos/vigojug/z-4up8hzjlq.md
@@ -0,0 +1,11 @@
+---
+sourceId: 'z_4Up8HzjLQ'
+groupId: 'vigojug'
+groupName: 'VigoJUG'
+groupLogo: 'https://vigotech.org/images/vigojug.jpg'
+title: 'Laretas Geek - Noviembre 2020 - Especial Kubernetes'
+player: 'youtube'
+url: 'https://www.youtube.com/watch?v=z_4Up8HzjLQ'
+publishedAt: null
+thumbnail: 'https://i.ytimg.com/vi/z_4Up8HzjLQ/hqdefault.jpg?sqp=-oaymwEcCNACELwBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==&rs=AOn4CLD7uvNxr6-lWyMFZPAdl3Pjp4mu9A'
+---
diff --git a/src/content/videos/vigojug/z1namxsblmi.md b/src/content/videos/vigojug/z1namxsblmi.md
new file mode 100644
index 00000000..49fb72e9
--- /dev/null
+++ b/src/content/videos/vigojug/z1namxsblmi.md
@@ -0,0 +1,11 @@
+---
+sourceId: 'Z1NAmxSbLMI'
+groupId: 'vigojug'
+groupName: 'VigoJUG'
+groupLogo: 'https://vigotech.org/images/vigojug.jpg'
+title: 'Laretas Geek - Mayo 2021 - Especial SpringBoot'
+player: 'youtube'
+url: 'https://www.youtube.com/watch?v=Z1NAmxSbLMI'
+publishedAt: 1622191197000
+thumbnail: 'https://i.ytimg.com/vi/Z1NAmxSbLMI/hqdefault.jpg'
+---
diff --git a/src/content/videos/vigowordpress/0sjwsqqywq8.md b/src/content/videos/vigowordpress/0sjwsqqywq8.md
new file mode 100644
index 00000000..c9289944
--- /dev/null
+++ b/src/content/videos/vigowordpress/0sjwsqqywq8.md
@@ -0,0 +1,11 @@
+---
+sourceId: '0SjwSQqYWQ8'
+groupId: 'vigowordpress'
+groupName: 'VigoWordpress'
+groupLogo: 'https://vigotech.org/images/vigowordpress.png'
+title: 'Meetup #02 - Jerarquía de plantillas, el ABC para desarrollar con WordPress'
+player: 'youtube'
+url: 'https://www.youtube.com/watch?v=0SjwSQqYWQ8'
+publishedAt: null
+thumbnail: 'https://i.ytimg.com/vi/0SjwSQqYWQ8/hqdefault.jpg?sqp=-oaymwEcCNACELwBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==&rs=AOn4CLBIaVz68Ahto_E3I8ZbT6ohIUCvhg'
+---
diff --git a/src/content/videos/vigowordpress/34nkuicspsm.md b/src/content/videos/vigowordpress/34nkuicspsm.md
new file mode 100644
index 00000000..644a1d2d
--- /dev/null
+++ b/src/content/videos/vigowordpress/34nkuicspsm.md
@@ -0,0 +1,11 @@
+---
+sourceId: '34NKuIcSPSM'
+groupId: 'vigowordpress'
+groupName: 'VigoWordpress'
+groupLogo: 'https://vigotech.org/images/vigowordpress.png'
+title: 'El bienestar corporativo y como multiplicar los resultados de la empresa'
+player: 'youtube'
+url: 'https://www.youtube.com/watch?v=34NKuIcSPSM'
+publishedAt: 1740058378000
+thumbnail: 'https://i.ytimg.com/vi/34NKuIcSPSM/hqdefault.jpg'
+---
diff --git a/src/content/videos/vigowordpress/axgsnbt9a3m.md b/src/content/videos/vigowordpress/axgsnbt9a3m.md
new file mode 100644
index 00000000..3ea78052
--- /dev/null
+++ b/src/content/videos/vigowordpress/axgsnbt9a3m.md
@@ -0,0 +1,11 @@
+---
+sourceId: 'AXgsnBT9A3M'
+groupId: 'vigowordpress'
+groupName: 'VigoWordpress'
+groupLogo: 'https://vigotech.org/images/vigowordpress.png'
+title: 'Ilustración, cómic y marca identidad ilustrada'
+player: 'youtube'
+url: 'https://www.youtube.com/watch?v=AXgsnBT9A3M'
+publishedAt: 1771546028000
+thumbnail: 'https://i.ytimg.com/vi/AXgsnBT9A3M/hqdefault.jpg'
+---
diff --git a/src/content/videos/vigowordpress/bqhakj6y7-q.md b/src/content/videos/vigowordpress/bqhakj6y7-q.md
new file mode 100644
index 00000000..6c3ad710
--- /dev/null
+++ b/src/content/videos/vigowordpress/bqhakj6y7-q.md
@@ -0,0 +1,11 @@
+---
+sourceId: 'bQhakj6y7-Q'
+groupId: 'vigowordpress'
+groupName: 'VigoWordpress'
+groupLogo: 'https://vigotech.org/images/vigowordpress.png'
+title: 'Factura electrónica vs Verifactu: Diferencias, obligaciones y soluciones'
+player: 'youtube'
+url: 'https://www.youtube.com/watch?v=bQhakj6y7-Q'
+publishedAt: 1755269193000
+thumbnail: 'https://i.ytimg.com/vi/bQhakj6y7-Q/hqdefault.jpg'
+---
diff --git a/src/content/videos/vigowordpress/cpgi6sqmbnw.md b/src/content/videos/vigowordpress/cpgi6sqmbnw.md
new file mode 100644
index 00000000..e75fbe11
--- /dev/null
+++ b/src/content/videos/vigowordpress/cpgi6sqmbnw.md
@@ -0,0 +1,11 @@
+---
+sourceId: 'cpGi6sQMbnw'
+groupId: 'vigowordpress'
+groupName: 'VigoWordpress'
+groupLogo: 'https://vigotech.org/images/vigowordpress.png'
+title: 'MeetUp WordPress Vigo 24 10 2023'
+player: 'youtube'
+url: 'https://www.youtube.com/watch?v=cpGi6sQMbnw'
+publishedAt: null
+thumbnail: 'https://i.ytimg.com/vi/cpGi6sQMbnw/hqdefault.jpg?sqp=-oaymwEcCNACELwBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==&rs=AOn4CLCMj3Aex_iu0pzOaD8LsSpPCEZR1A'
+---
diff --git a/src/content/videos/vigowordpress/cqamk4jm5y0.md b/src/content/videos/vigowordpress/cqamk4jm5y0.md
new file mode 100644
index 00000000..973e30a0
--- /dev/null
+++ b/src/content/videos/vigowordpress/cqamk4jm5y0.md
@@ -0,0 +1,11 @@
+---
+sourceId: 'cQaMK4jm5Y0'
+groupId: 'vigowordpress'
+groupName: 'VigoWordpress'
+groupLogo: 'https://vigotech.org/images/vigowordpress.png'
+title: 'Los ingredientes de una buena estrategia de DATA DRIVEN en las campañas de publicidad'
+player: 'youtube'
+url: 'https://www.youtube.com/watch?v=cQaMK4jm5Y0'
+publishedAt: null
+thumbnail: 'https://i.ytimg.com/vi/cQaMK4jm5Y0/hqdefault.jpg?sqp=-oaymwE2CNACELwBSFXyq4qpAygIARUAAIhCGAFwAcABBvABAfgB_gmAAtAFigIMCAAQARhyIF8oRTAP&rs=AOn4CLCcK9G0CKu3Vh4Vf4vL1HhUE-hD1A'
+---
diff --git a/src/content/videos/vigowordpress/djlp6vgnttu.md b/src/content/videos/vigowordpress/djlp6vgnttu.md
new file mode 100644
index 00000000..8fcb6993
--- /dev/null
+++ b/src/content/videos/vigowordpress/djlp6vgnttu.md
@@ -0,0 +1,11 @@
+---
+sourceId: 'DjLP6VgNtTU'
+groupId: 'vigowordpress'
+groupName: 'VigoWordpress'
+groupLogo: 'https://vigotech.org/images/vigowordpress.png'
+title: 'Meetup #12 - WooCommerce no es solo una tienda online'
+player: 'youtube'
+url: 'https://www.youtube.com/watch?v=DjLP6VgNtTU'
+publishedAt: null
+thumbnail: 'https://i.ytimg.com/vi/DjLP6VgNtTU/hqdefault.jpg?sqp=-oaymwEcCNACELwBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==&rs=AOn4CLAlOxci9PNsXVYkiCgU6nuYLpQmMQ'
+---
diff --git a/src/content/videos/vigowordpress/dujalqnvve8.md b/src/content/videos/vigowordpress/dujalqnvve8.md
new file mode 100644
index 00000000..df9f93b3
--- /dev/null
+++ b/src/content/videos/vigowordpress/dujalqnvve8.md
@@ -0,0 +1,11 @@
+---
+sourceId: 'DuJaLqNVVe8'
+groupId: 'vigowordpress'
+groupName: 'VigoWordpress'
+groupLogo: 'https://vigotech.org/images/vigowordpress.png'
+title: 'Meetup #03 - RRSS y su importancia en los negocios digitales'
+player: 'youtube'
+url: 'https://www.youtube.com/watch?v=DuJaLqNVVe8'
+publishedAt: null
+thumbnail: 'https://i.ytimg.com/vi/DuJaLqNVVe8/hqdefault.jpg?sqp=-oaymwEcCNACELwBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==&rs=AOn4CLCZ0YRqSo8gtbhnePXMdJvWpMWAew'
+---
diff --git a/src/content/videos/vigowordpress/evo7vic0b80.md b/src/content/videos/vigowordpress/evo7vic0b80.md
new file mode 100644
index 00000000..096e8e19
--- /dev/null
+++ b/src/content/videos/vigowordpress/evo7vic0b80.md
@@ -0,0 +1,11 @@
+---
+sourceId: 'EVo7vic0b80'
+groupId: 'vigowordpress'
+groupName: 'VigoWordpress'
+groupLogo: 'https://vigotech.org/images/vigowordpress.png'
+title: 'Meetup #07 - ¿Y después qué?'
+player: 'youtube'
+url: 'https://www.youtube.com/watch?v=EVo7vic0b80'
+publishedAt: null
+thumbnail: 'https://i.ytimg.com/vi/EVo7vic0b80/hqdefault.jpg?sqp=-oaymwE2CNACELwBSFXyq4qpAygIARUAAIhCGAFwAcABBvABAfgB1AaAAuADigIMCAAQARhlIGUoZTAP&rs=AOn4CLCBPydnzlMyMCQIKe_KCwbNN8i8oQ'
+---
diff --git a/src/content/videos/vigowordpress/gbqce-yn7bi.md b/src/content/videos/vigowordpress/gbqce-yn7bi.md
new file mode 100644
index 00000000..7215aa4e
--- /dev/null
+++ b/src/content/videos/vigowordpress/gbqce-yn7bi.md
@@ -0,0 +1,11 @@
+---
+sourceId: 'GbqcE-YN7BI'
+groupId: 'vigowordpress'
+groupName: 'VigoWordpress'
+groupLogo: 'https://vigotech.org/images/vigowordpress.png'
+title: 'Creando asistentes virtuales con Inteligencia Artificial'
+player: 'youtube'
+url: 'https://www.youtube.com/watch?v=GbqcE-YN7BI'
+publishedAt: 1740059082000
+thumbnail: 'https://i.ytimg.com/vi/GbqcE-YN7BI/hqdefault.jpg'
+---
diff --git a/src/content/videos/vigowordpress/ic-typrnn6u.md b/src/content/videos/vigowordpress/ic-typrnn6u.md
new file mode 100644
index 00000000..af2c5850
--- /dev/null
+++ b/src/content/videos/vigowordpress/ic-typrnn6u.md
@@ -0,0 +1,11 @@
+---
+sourceId: 'iC-typrnn6U'
+groupId: 'vigowordpress'
+groupName: 'VigoWordpress'
+groupLogo: 'https://vigotech.org/images/vigowordpress.png'
+title: 'Meetup #06 - Dominios y hostings: el interrogatorio'
+player: 'youtube'
+url: 'https://www.youtube.com/watch?v=iC-typrnn6U'
+publishedAt: null
+thumbnail: 'https://i.ytimg.com/vi/iC-typrnn6U/hqdefault.jpg?sqp=-oaymwEcCNACELwBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==&rs=AOn4CLBJXQpQG8fyICqjae5sRBKYgDKbMg'
+---
diff --git a/src/content/videos/vigowordpress/il-zcyigfuo.md b/src/content/videos/vigowordpress/il-zcyigfuo.md
new file mode 100644
index 00000000..d024a29a
--- /dev/null
+++ b/src/content/videos/vigowordpress/il-zcyigfuo.md
@@ -0,0 +1,11 @@
+---
+sourceId: 'il_ZCYIgFUo'
+groupId: 'vigowordpress'
+groupName: 'VigoWordpress'
+groupLogo: 'https://vigotech.org/images/vigowordpress.png'
+title: 'Manteniendo la tradición en un eCommerce: Cómo Peperetes preserva lo artesanal'
+player: 'youtube'
+url: 'https://www.youtube.com/watch?v=il_ZCYIgFUo'
+publishedAt: 1723127427000
+thumbnail: 'https://i.ytimg.com/vi/il_ZCYIgFUo/hqdefault.jpg'
+---
diff --git a/src/content/videos/vigowordpress/iwd72h69xqo.md b/src/content/videos/vigowordpress/iwd72h69xqo.md
new file mode 100644
index 00000000..9046bc22
--- /dev/null
+++ b/src/content/videos/vigowordpress/iwd72h69xqo.md
@@ -0,0 +1,11 @@
+---
+sourceId: 'IWd72H69Xqo'
+groupId: 'vigowordpress'
+groupName: 'VigoWordpress'
+groupLogo: 'https://vigotech.org/images/vigowordpress.png'
+title: 'Convertir emoción en experiencias digitales'
+player: 'youtube'
+url: 'https://www.youtube.com/watch?v=IWd72H69Xqo'
+publishedAt: 1772216306000
+thumbnail: 'https://i.ytimg.com/vi/IWd72H69Xqo/hqdefault.jpg'
+---
diff --git a/src/content/videos/vigowordpress/kl6cev339mo.md b/src/content/videos/vigowordpress/kl6cev339mo.md
new file mode 100644
index 00000000..3897a3f8
--- /dev/null
+++ b/src/content/videos/vigowordpress/kl6cev339mo.md
@@ -0,0 +1,11 @@
+---
+sourceId: 'KL6cev339Mo'
+groupId: 'vigowordpress'
+groupName: 'VigoWordpress'
+groupLogo: 'https://vigotech.org/images/vigowordpress.png'
+title: 'Meetup #05 - Cómo ser un profesional freelance legal'
+player: 'youtube'
+url: 'https://www.youtube.com/watch?v=KL6cev339Mo'
+publishedAt: null
+thumbnail: 'https://i.ytimg.com/vi/KL6cev339Mo/hqdefault.jpg?sqp=-oaymwEcCNACELwBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==&rs=AOn4CLBXEbhduoB1uhpqEdNvOxkE0MQKcQ'
+---
diff --git a/src/content/videos/vigowordpress/kpsqflq9dpq.md b/src/content/videos/vigowordpress/kpsqflq9dpq.md
new file mode 100644
index 00000000..fb19985b
--- /dev/null
+++ b/src/content/videos/vigowordpress/kpsqflq9dpq.md
@@ -0,0 +1,11 @@
+---
+sourceId: 'kPsqFlq9DPQ'
+groupId: 'vigowordpress'
+groupName: 'VigoWordpress'
+groupLogo: 'https://vigotech.org/images/vigowordpress.png'
+title: 'Meetup #09 - Modelo de negocio de un profesional freelance'
+player: 'youtube'
+url: 'https://www.youtube.com/watch?v=kPsqFlq9DPQ'
+publishedAt: null
+thumbnail: 'https://i.ytimg.com/vi/kPsqFlq9DPQ/hqdefault.jpg?sqp=-oaymwEcCNACELwBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==&rs=AOn4CLCo7V6W9LWtw9Rr7uUMmUpUNnaYAQ'
+---
diff --git a/src/content/videos/vigowordpress/kstyiqqofae.md b/src/content/videos/vigowordpress/kstyiqqofae.md
new file mode 100644
index 00000000..997f5ba9
--- /dev/null
+++ b/src/content/videos/vigowordpress/kstyiqqofae.md
@@ -0,0 +1,11 @@
+---
+sourceId: 'kstyIQqofaE'
+groupId: 'vigowordpress'
+groupName: 'VigoWordpress'
+groupLogo: 'https://vigotech.org/images/vigowordpress.png'
+title: 'Meetup #17 - ¿Tienes un ecommerce y no consigues vender lo que esperabas?'
+player: 'youtube'
+url: 'https://www.youtube.com/watch?v=kstyIQqofaE'
+publishedAt: null
+thumbnail: 'https://i.ytimg.com/vi/kstyIQqofaE/hqdefault.jpg?sqp=-oaymwEcCNACELwBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==&rs=AOn4CLA-ZrQKjmYUytKH-7G0dAG0Gf8_FQ'
+---
diff --git a/src/content/videos/vigowordpress/l6asdje-2vc.md b/src/content/videos/vigowordpress/l6asdje-2vc.md
new file mode 100644
index 00000000..b0931d8e
--- /dev/null
+++ b/src/content/videos/vigowordpress/l6asdje-2vc.md
@@ -0,0 +1,11 @@
+---
+sourceId: 'L6aSDjE_2Vc'
+groupId: 'vigowordpress'
+groupName: 'VigoWordpress'
+groupLogo: 'https://vigotech.org/images/vigowordpress.png'
+title: 'Meetup #11 - Cómo gestionar una gran cantidad de sitios WordPress'
+player: 'youtube'
+url: 'https://www.youtube.com/watch?v=L6aSDjE_2Vc'
+publishedAt: null
+thumbnail: 'https://i.ytimg.com/vi/L6aSDjE_2Vc/hqdefault.jpg?sqp=-oaymwEcCNACELwBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==&rs=AOn4CLDV6Blw9i5Au2jOWV-qzntyOSEcvQ'
+---
diff --git a/src/content/videos/vigowordpress/llac-qs9fj8.md b/src/content/videos/vigowordpress/llac-qs9fj8.md
new file mode 100644
index 00000000..e353271c
--- /dev/null
+++ b/src/content/videos/vigowordpress/llac-qs9fj8.md
@@ -0,0 +1,11 @@
+---
+sourceId: 'lLac-qS9fj8'
+groupId: 'vigowordpress'
+groupName: 'VigoWordpress'
+groupLogo: 'https://vigotech.org/images/vigowordpress.png'
+title: 'Meetup #01 - Plugins recomendados para WordPress y cómo crear el tuyo'
+player: 'youtube'
+url: 'https://www.youtube.com/watch?v=lLac-qS9fj8'
+publishedAt: null
+thumbnail: 'https://i.ytimg.com/vi/lLac-qS9fj8/hqdefault.jpg?sqp=-oaymwEcCNACELwBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==&rs=AOn4CLCI1xCdE7q56DS3Yp2CIwA3YWSNLQ'
+---
diff --git a/src/content/videos/vigowordpress/lu3cuxdgegw.md b/src/content/videos/vigowordpress/lu3cuxdgegw.md
new file mode 100644
index 00000000..0f2cd917
--- /dev/null
+++ b/src/content/videos/vigowordpress/lu3cuxdgegw.md
@@ -0,0 +1,11 @@
+---
+sourceId: 'Lu3Cuxdgegw'
+groupId: 'vigowordpress'
+groupName: 'VigoWordpress'
+groupLogo: 'https://vigotech.org/images/vigowordpress.png'
+title: 'Aspectos legales del desarrollo de software'
+player: 'youtube'
+url: 'https://www.youtube.com/watch?v=Lu3Cuxdgegw'
+publishedAt: 1771546982000
+thumbnail: 'https://i.ytimg.com/vi/Lu3Cuxdgegw/hqdefault.jpg'
+---
diff --git a/src/content/videos/vigowordpress/o-z-8jx5eok.md b/src/content/videos/vigowordpress/o-z-8jx5eok.md
new file mode 100644
index 00000000..72ba17d3
--- /dev/null
+++ b/src/content/videos/vigowordpress/o-z-8jx5eok.md
@@ -0,0 +1,11 @@
+---
+sourceId: 'O-z_8jx5EOk'
+groupId: 'vigowordpress'
+groupName: 'VigoWordpress'
+groupLogo: 'https://vigotech.org/images/vigowordpress.png'
+title: 'Cómo construir una marca sólida y generar ventas a través del contenido gratuito'
+player: 'youtube'
+url: 'https://www.youtube.com/watch?v=O-z_8jx5EOk'
+publishedAt: 1770665988000
+thumbnail: 'https://i.ytimg.com/vi/O-z_8jx5EOk/hqdefault.jpg'
+---
diff --git a/src/content/videos/vigowordpress/oq-hsvww4hi.md b/src/content/videos/vigowordpress/oq-hsvww4hi.md
new file mode 100644
index 00000000..45b2f2bc
--- /dev/null
+++ b/src/content/videos/vigowordpress/oq-hsvww4hi.md
@@ -0,0 +1,11 @@
+---
+sourceId: 'oQ-hSvWw4HI'
+groupId: 'vigowordpress'
+groupName: 'VigoWordpress'
+groupLogo: 'https://vigotech.org/images/vigowordpress.png'
+title: 'Meetup #08 - WordPress: Campamento base de tu Marca Personal'
+player: 'youtube'
+url: 'https://www.youtube.com/watch?v=oQ-hSvWw4HI'
+publishedAt: null
+thumbnail: 'https://i.ytimg.com/vi/oQ-hSvWw4HI/hqdefault.jpg?sqp=-oaymwEcCNACELwBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==&rs=AOn4CLBpGDmILGD8e7LQ5ugDckc-kgapoA'
+---
diff --git a/src/content/videos/vigowordpress/oxqql7jxcgi.md b/src/content/videos/vigowordpress/oxqql7jxcgi.md
new file mode 100644
index 00000000..d041e531
--- /dev/null
+++ b/src/content/videos/vigowordpress/oxqql7jxcgi.md
@@ -0,0 +1,11 @@
+---
+sourceId: 'OXqQL7jXCGI'
+groupId: 'vigowordpress'
+groupName: 'VigoWordpress'
+groupLogo: 'https://vigotech.org/images/vigowordpress.png'
+title: 'Green Web diseños web eficientes, optimizados y de transferencia de datos reducida'
+player: 'youtube'
+url: 'https://www.youtube.com/watch?v=OXqQL7jXCGI'
+publishedAt: 1709675437000
+thumbnail: 'https://i.ytimg.com/vi/OXqQL7jXCGI/hqdefault.jpg'
+---
diff --git a/src/content/videos/vigowordpress/p4qkypydt3s.md b/src/content/videos/vigowordpress/p4qkypydt3s.md
new file mode 100644
index 00000000..073032b0
--- /dev/null
+++ b/src/content/videos/vigowordpress/p4qkypydt3s.md
@@ -0,0 +1,11 @@
+---
+sourceId: 'p4qKYpYDT3s'
+groupId: 'vigowordpress'
+groupName: 'VigoWordpress'
+groupLogo: 'https://vigotech.org/images/vigowordpress.png'
+title: 'Internacionalización de empresas: La era de la exportación digital'
+player: 'youtube'
+url: 'https://www.youtube.com/watch?v=p4qKYpYDT3s'
+publishedAt: 1709255538000
+thumbnail: 'https://i.ytimg.com/vi/p4qKYpYDT3s/hqdefault.jpg'
+---
diff --git a/src/content/videos/vigowordpress/quj83yrodhs.md b/src/content/videos/vigowordpress/quj83yrodhs.md
new file mode 100644
index 00000000..c6d9af77
--- /dev/null
+++ b/src/content/videos/vigowordpress/quj83yrodhs.md
@@ -0,0 +1,11 @@
+---
+sourceId: 'quj83YRodhs'
+groupId: 'vigowordpress'
+groupName: 'VigoWordpress'
+groupLogo: 'https://vigotech.org/images/vigowordpress.png'
+title: 'SEO Local: Cómo ser uno de los tres elegidos de Google'
+player: 'youtube'
+url: 'https://www.youtube.com/watch?v=quj83YRodhs'
+publishedAt: 1711390702000
+thumbnail: 'https://i.ytimg.com/vi/quj83YRodhs/hqdefault.jpg'
+---
diff --git a/src/content/videos/vigowordpress/rtnoqecgakc.md b/src/content/videos/vigowordpress/rtnoqecgakc.md
new file mode 100644
index 00000000..5dd17bd6
--- /dev/null
+++ b/src/content/videos/vigowordpress/rtnoqecgakc.md
@@ -0,0 +1,11 @@
+---
+sourceId: 'RtnOqeCGAKc'
+groupId: 'vigowordpress'
+groupName: 'VigoWordpress'
+groupLogo: 'https://vigotech.org/images/vigowordpress.png'
+title: 'Meetup #13 - Bailaré sobre tu SEO: Google, WordPress y otras historias del punk'
+player: 'youtube'
+url: 'https://www.youtube.com/watch?v=RtnOqeCGAKc'
+publishedAt: null
+thumbnail: 'https://i.ytimg.com/vi/RtnOqeCGAKc/hqdefault.jpg?sqp=-oaymwEcCNACELwBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==&rs=AOn4CLDd1u-ZyqVF64q5eM5nbMqhIeUywg'
+---
diff --git a/src/content/videos/vigowordpress/t8ecwcrslsa.md b/src/content/videos/vigowordpress/t8ecwcrslsa.md
new file mode 100644
index 00000000..38535a05
--- /dev/null
+++ b/src/content/videos/vigowordpress/t8ecwcrslsa.md
@@ -0,0 +1,11 @@
+---
+sourceId: 't8ECwCRSlsA'
+groupId: 'vigowordpress'
+groupName: 'VigoWordpress'
+groupLogo: 'https://vigotech.org/images/vigowordpress.png'
+title: 'Meetup #14 - Encuentra y lanza tu idea de negocio'
+player: 'youtube'
+url: 'https://www.youtube.com/watch?v=t8ECwCRSlsA'
+publishedAt: null
+thumbnail: 'https://i.ytimg.com/vi/t8ECwCRSlsA/hqdefault.jpg?sqp=-oaymwEcCNACELwBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==&rs=AOn4CLAwvpdbyNGrDeD3xQnwObPghLsz3g'
+---
diff --git a/src/content/videos/vigowordpress/umjgn-gtid0.md b/src/content/videos/vigowordpress/umjgn-gtid0.md
new file mode 100644
index 00000000..05327ab9
--- /dev/null
+++ b/src/content/videos/vigowordpress/umjgn-gtid0.md
@@ -0,0 +1,11 @@
+---
+sourceId: 'uMJGN-gTid0'
+groupId: 'vigowordpress'
+groupName: 'VigoWordpress'
+groupLogo: 'https://vigotech.org/images/vigowordpress.png'
+title: 'Meetup #04 - CoP: Comunidades de práctica online'
+player: 'youtube'
+url: 'https://www.youtube.com/watch?v=uMJGN-gTid0'
+publishedAt: null
+thumbnail: 'https://i.ytimg.com/vi/uMJGN-gTid0/hqdefault.jpg?sqp=-oaymwEcCNACELwBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==&rs=AOn4CLCt-aJ7w9JMIUIYZ9aMHTutpULMiw'
+---
diff --git a/src/content/videos/vigowordpress/wjvxjbgmk9a.md b/src/content/videos/vigowordpress/wjvxjbgmk9a.md
new file mode 100644
index 00000000..061df57d
--- /dev/null
+++ b/src/content/videos/vigowordpress/wjvxjbgmk9a.md
@@ -0,0 +1,11 @@
+---
+sourceId: 'wJvxjbGmK9A'
+groupId: 'vigowordpress'
+groupName: 'VigoWordpress'
+groupLogo: 'https://vigotech.org/images/vigowordpress.png'
+title: 'Meetup #10 - ¿Cuánto cuesta una web? Y, ¿como poner en valor mi trabajo?'
+player: 'youtube'
+url: 'https://www.youtube.com/watch?v=wJvxjbGmK9A'
+publishedAt: null
+thumbnail: 'https://i.ytimg.com/vi/wJvxjbGmK9A/hqdefault.jpg?sqp=-oaymwEcCNACELwBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==&rs=AOn4CLDJQ8m1KRulUybA_sZpsnrpbvqSaA'
+---
diff --git a/src/content/videos/vigowordpress/wn3dyenpw4m.md b/src/content/videos/vigowordpress/wn3dyenpw4m.md
new file mode 100644
index 00000000..d654f45c
--- /dev/null
+++ b/src/content/videos/vigowordpress/wn3dyenpw4m.md
@@ -0,0 +1,11 @@
+---
+sourceId: 'WN3dyEnpW4M'
+groupId: 'vigowordpress'
+groupName: 'VigoWordpress'
+groupLogo: 'https://vigotech.org/images/vigowordpress.png'
+title: 'Meetup #16 - WebP, un formato para dominarlos a todos'
+player: 'youtube'
+url: 'https://www.youtube.com/watch?v=WN3dyEnpW4M'
+publishedAt: null
+thumbnail: 'https://i.ytimg.com/vi/WN3dyEnpW4M/hqdefault.jpg?sqp=-oaymwEcCNACELwBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==&rs=AOn4CLAvzeHcEoh0-1FLMUsVQStKcyv-CA'
+---
diff --git a/src/content/videos/vigowordpress/x-j-xwr3dwc.md b/src/content/videos/vigowordpress/x-j-xwr3dwc.md
new file mode 100644
index 00000000..60da96bf
--- /dev/null
+++ b/src/content/videos/vigowordpress/x-j-xwr3dwc.md
@@ -0,0 +1,11 @@
+---
+sourceId: 'x_J_XWR3dwc'
+groupId: 'vigowordpress'
+groupName: 'VigoWordpress'
+groupLogo: 'https://vigotech.org/images/vigowordpress.png'
+title: 'No dejes la puerta abierta ciberseguridad para WordPress'
+player: 'youtube'
+url: 'https://www.youtube.com/watch?v=x_J_XWR3dwc'
+publishedAt: 1759346680000
+thumbnail: 'https://i.ytimg.com/vi/x_J_XWR3dwc/hqdefault.jpg'
+---
diff --git a/src/content/videos/vigowordpress/yhyx0ao6zci.md b/src/content/videos/vigowordpress/yhyx0ao6zci.md
new file mode 100644
index 00000000..99b0f89f
--- /dev/null
+++ b/src/content/videos/vigowordpress/yhyx0ao6zci.md
@@ -0,0 +1,11 @@
+---
+sourceId: 'YHyx0ao6zCI'
+groupId: 'vigowordpress'
+groupName: 'VigoWordpress'
+groupLogo: 'https://vigotech.org/images/vigowordpress.png'
+title: 'Impacto y experiencia del do_action WCVIGO2024'
+player: 'youtube'
+url: 'https://www.youtube.com/watch?v=YHyx0ao6zCI'
+publishedAt: 1740051769000
+thumbnail: 'https://i.ytimg.com/vi/YHyx0ao6zCI/hqdefault.jpg'
+---
diff --git a/src/content/videos/vigowordpress/yx79lpgolku.md b/src/content/videos/vigowordpress/yx79lpgolku.md
new file mode 100644
index 00000000..90fa95c0
--- /dev/null
+++ b/src/content/videos/vigowordpress/yx79lpgolku.md
@@ -0,0 +1,11 @@
+---
+sourceId: 'yX79lPGolKU'
+groupId: 'vigowordpress'
+groupName: 'VigoWordpress'
+groupLogo: 'https://vigotech.org/images/vigowordpress.png'
+title: 'IA generativa y marketing real: cómo ahorrar tiempo, vender más y fidelizar mejor'
+player: 'youtube'
+url: 'https://www.youtube.com/watch?v=yX79lPGolKU'
+publishedAt: 1748937342000
+thumbnail: 'https://i.ytimg.com/vi/yX79lPGolKU/hqdefault.jpg'
+---
diff --git a/src/content/videos/vigowordpress/z7uyexby9ra.md b/src/content/videos/vigowordpress/z7uyexby9ra.md
new file mode 100644
index 00000000..7e817738
--- /dev/null
+++ b/src/content/videos/vigowordpress/z7uyexby9ra.md
@@ -0,0 +1,11 @@
+---
+sourceId: 'Z7uyExBY9rA'
+groupId: 'vigowordpress'
+groupName: 'VigoWordpress'
+groupLogo: 'https://vigotech.org/images/vigowordpress.png'
+title: 'Haz que te encuentren cómo destacar tu perfil profesional y atraer oportunidades'
+player: 'youtube'
+url: 'https://www.youtube.com/watch?v=Z7uyExBY9rA'
+publishedAt: 1771546621000
+thumbnail: 'https://i.ytimg.com/vi/Z7uyExBY9rA/hqdefault.jpg'
+---
diff --git a/src/i18n/calendar.ts b/src/i18n/calendar.ts
new file mode 100644
index 00000000..eed71e99
--- /dev/null
+++ b/src/i18n/calendar.ts
@@ -0,0 +1,16 @@
+export const calendarT = {
+ gl: {
+ heading: 'Axenda',
+ lead: 'Consulta as proximas actividades da comunidade en tempo real.',
+ loading: 'Cargando eventos...',
+ empty: 'Agora mesmo non hai eventos publicados na axenda.',
+ error: 'Non se puido cargar a axenda neste intre.',
+ viewMonth: 'Mes',
+ viewWeek: 'Semana',
+ at: 'As',
+ atLocation: 'En',
+ allDay: 'Todo o dia',
+ openEvent: 'Abrir evento',
+ openIcs: 'Descargar iCal',
+ },
+} as const
diff --git a/src/i18n/config.ts b/src/i18n/config.ts
new file mode 100644
index 00000000..e1563849
--- /dev/null
+++ b/src/i18n/config.ts
@@ -0,0 +1,9 @@
+export const LANG = 'gl' as const
+
+export const LOCALE_BY_LANG = {
+ gl: 'gl-ES',
+} as const
+
+export type Lang = keyof typeof LOCALE_BY_LANG
+
+export const LOCALE = LOCALE_BY_LANG[LANG]
diff --git a/src/i18n/doc-page.ts b/src/i18n/doc-page.ts
new file mode 100644
index 00000000..411d8606
--- /dev/null
+++ b/src/i18n/doc-page.ts
@@ -0,0 +1,38 @@
+export const docPageT = {
+ gl: {
+ leads: {
+ 'codigo-conduta': {
+ badge: 'Gobernanza',
+ description:
+ 'Define o marco etico do noso colectivo tecnico. Priorizamos as persoas por enriba das maquinas e a colaboracion por enriba da competencia.',
+ },
+ 'codigo-conduta-slack': {
+ badge: 'Comunidade',
+ description:
+ 'Normas para unha participacion respectuosa e construtiva no espazo de Slack de VigoTech.',
+ },
+ manifesto: {
+ badge: 'Principios',
+ description:
+ 'Proposito compartido, valores e direccion a longo prazo das comunidades da VigoTech Alliance.',
+ },
+ 'condicions-entrada': {
+ badge: 'Politica',
+ description:
+ 'Termos e condicions de participacion para eventos e iniciativas do ecosistema VigoTech.',
+ },
+ default: {
+ badge: 'Documento',
+ description: 'Referencia editorial para membros e colaboradoras da VigoTech Alliance.',
+ },
+ },
+ tocLabel: 'Indice',
+ noSections: 'Sen seccions dispoñibles',
+ fallbackSection: 'Seccion',
+ reportHeading: 'Necesitas reportar algo?',
+ reportDescription:
+ 'Se detectas un comportamento que incumpre este documento, contacta co equipo de VigoTech.',
+ reportButton: 'Contactar co equipo de conduta',
+ sourceMarkdown: 'Markdown orixinal',
+ },
+} as const
diff --git a/src/i18n/footer.ts b/src/i18n/footer.ts
new file mode 100644
index 00000000..8284e826
--- /dev/null
+++ b/src/i18n/footer.ts
@@ -0,0 +1,11 @@
+export const footerT = {
+ gl: {
+ brand: 'VigoTech Alliance',
+ links: {
+ codeOfConduct: 'Codigo de conduta',
+ conditions: 'Condicions de entrada',
+ slackPolicy: 'Conduta en Slack',
+ },
+ copyright: 'VigoTech Alliance',
+ },
+} as const
diff --git a/src/i18n/groups.ts b/src/i18n/groups.ts
new file mode 100644
index 00000000..6f978dda
--- /dev/null
+++ b/src/i18n/groups.ts
@@ -0,0 +1,19 @@
+export const groupsT = {
+ gl: {
+ heading: 'Comunidades',
+ directoryEyebrow: 'Directorio do ecosistema',
+ directoryTitle: 'Intelixencia **colectiva**.',
+ activeHeading: 'Comunidades activas',
+ videosLabel: 'videos',
+ communityLabel: 'Comunidade',
+ active: 'Activa',
+ inactive: 'Inactiva',
+ searchPlaceholder: 'Buscar comunidades por nome...',
+ filterActive: 'Activas',
+ filterInactive: 'Inactive',
+ filterAll: 'Todas',
+ emptyResults: 'Non hai comunidades para este filtro.',
+ joinCommunity: 'Unirse a comunidade',
+ viewVideos: 'Ver vídeos',
+ },
+} as const
diff --git a/src/i18n/header.ts b/src/i18n/header.ts
new file mode 100644
index 00000000..bfb267eb
--- /dev/null
+++ b/src/i18n/header.ts
@@ -0,0 +1,11 @@
+export const headerT = {
+ gl: {
+ logoAria: 'VigoTech Alliance',
+ menu: {
+ home: 'Inicio',
+ groups: 'Grupos',
+ videos: 'Videos',
+ about: 'Manifesto',
+ },
+ },
+} as const
diff --git a/src/i18n/home-conversation.ts b/src/i18n/home-conversation.ts
new file mode 100644
index 00000000..bf90a6a0
--- /dev/null
+++ b/src/i18n/home-conversation.ts
@@ -0,0 +1,24 @@
+export const homeConversationT = {
+ gl: {
+ heading: 'Unete a conversa',
+ description:
+ 'Aberto a todo o mundo, e o punto de encontro virtual de todos os grupos e un bo sitio para facer networking.',
+ joinSlack: 'Consegue unha invitacion no teu correo premendo aqui',
+ links: {
+ twitter: 'Twitter',
+ telegram: 'Telegram',
+ email: 'Email',
+ github: 'GitHub',
+ },
+ social: {
+ twitter: 'https://twitter.com/vigotechallianc',
+ telegram: 'https://t.me/vigotech',
+ email: 'mailto:alliance@vigotech.org',
+ github: 'https://github.com/VigoTech',
+ },
+ slack: {
+ workspace: 'https://vigotechalliance.slack.com',
+ invite: 'https://slackin-vigotech.herokuapp.com/',
+ },
+ },
+} as const
diff --git a/src/i18n/home-documents.ts b/src/i18n/home-documents.ts
new file mode 100644
index 00000000..7efff072
--- /dev/null
+++ b/src/i18n/home-documents.ts
@@ -0,0 +1,5 @@
+export const homeDocumentsT = {
+ gl: {
+ // component only renders document titles from content entries
+ },
+} as const
diff --git a/src/i18n/home-friends.ts b/src/i18n/home-friends.ts
new file mode 100644
index 00000000..4f1e240e
--- /dev/null
+++ b/src/i18n/home-friends.ts
@@ -0,0 +1,5 @@
+export const homeFriendsT = {
+ gl: {
+ heading: 'Amigxs',
+ },
+} as const
diff --git a/src/i18n/home-groups.ts b/src/i18n/home-groups.ts
new file mode 100644
index 00000000..926fc0bb
--- /dev/null
+++ b/src/i18n/home-groups.ts
@@ -0,0 +1,7 @@
+export const homeGroupsT = {
+ gl: {
+ heading: 'Comunidades activas',
+ videosLabel: 'videos',
+ communityLabel: 'Comunidade',
+ },
+} as const
diff --git a/src/i18n/home-hero.ts b/src/i18n/home-hero.ts
new file mode 100644
index 00000000..99692872
--- /dev/null
+++ b/src/i18n/home-hero.ts
@@ -0,0 +1,10 @@
+export const homeHeroT = {
+ gl: {
+ titleMarkdown: 'Os grupos de tecnoloxía de Vigo **facemos piña**',
+ description:
+ 'Un ecosistema federado de comunidades tecnicas, hackers e innovadores. Unimos precision tecnica e conexion humana para visibilizar o movemento local.',
+ exploreButton: 'Explora o ecosistema',
+ upcomingEvents: 'Proximos eventos',
+ viewEvent: 'Ver evento',
+ },
+} as const
diff --git a/src/i18n/home-videos-preview.ts b/src/i18n/home-videos-preview.ts
new file mode 100644
index 00000000..352b5f62
--- /dev/null
+++ b/src/i18n/home-videos-preview.ts
@@ -0,0 +1,11 @@
+export const homeVideosPreviewT = {
+ gl: {
+ heading: 'Mantente ao dia',
+ description:
+ 'Recibe novidades mensuais sobre os eventos da comunidade e as novas publicacions en video da rede VigoTech.',
+ emailPlaceholder: 'Introduce o teu email',
+ subscribe: 'Subscribirme',
+ viewVideosPrefix: 'Ver',
+ viewVideosSuffix: 'videos dispoñibles',
+ },
+} as const
diff --git a/src/i18n/home-videos.ts b/src/i18n/home-videos.ts
new file mode 100644
index 00000000..1f9db050
--- /dev/null
+++ b/src/i18n/home-videos.ts
@@ -0,0 +1,8 @@
+export const homeVideosT = {
+ gl: {
+ eyebrow: 'Ultimos contidos',
+ heading: 'Videos recentes',
+ watchNow: 'Ver agora',
+ viewAll: 'Ir a todos os videos',
+ },
+} as const
diff --git a/src/i18n/theme-toggle.ts b/src/i18n/theme-toggle.ts
new file mode 100644
index 00000000..e068cb5b
--- /dev/null
+++ b/src/i18n/theme-toggle.ts
@@ -0,0 +1,8 @@
+export const themeToggleT = {
+ gl: {
+ ariaLabel: 'Alternar modo escuro',
+ title: 'Alternar modo escuro',
+ darkMode: 'Modo escuro',
+ lightMode: 'Modo claro',
+ },
+} as const
diff --git a/src/i18n/videos-browser.ts b/src/i18n/videos-browser.ts
new file mode 100644
index 00000000..401549af
--- /dev/null
+++ b/src/i18n/videos-browser.ts
@@ -0,0 +1,11 @@
+export const videosBrowserT = {
+ gl: {
+ eyebrow: 'Arquivo audiovisual',
+ heading: 'Biblioteca de **videos**.',
+ searchPlaceholder: 'Buscar por titulo ou grupo...',
+ allGroups: 'Todos os grupos',
+ sortByDate: 'Orde por data',
+ watchNow: 'Ver agora',
+ emptyResults: 'Non hai resultados cos filtros actuais.',
+ },
+} as const
diff --git a/src/layouts/BaseLayout.astro b/src/layouts/BaseLayout.astro
new file mode 100644
index 00000000..863781f6
--- /dev/null
+++ b/src/layouts/BaseLayout.astro
@@ -0,0 +1,104 @@
+---
+import { withBase } from '../lib/base-path'
+import ThemeScript from '../components/theme/ThemeScript.astro'
+import Footer from '../components/layout/Footer.astro'
+import Header from '../components/layout/Header.astro'
+import '../styles/global.css'
+
+type Props = {
+ title?: string
+ description?: string
+ mainClass?: string
+}
+
+const {
+ title = 'VigoTech Alliance',
+ description = 'Federated ecosystem of tech communities from Vigo',
+ mainClass = 'pt-28',
+} = Astro.props
+
+const shouldNoIndex = import.meta.env.PUBLIC_NOINDEX === 'true'
+---
+
+
+
+
+
+
+
+
+ {shouldNoIndex && }
+ {title}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/lib/base-path.ts b/src/lib/base-path.ts
new file mode 100644
index 00000000..e0e08079
--- /dev/null
+++ b/src/lib/base-path.ts
@@ -0,0 +1,42 @@
+const normalizeConfiguredBase = (value: string | undefined): string => {
+ const trimmed = value?.trim()
+
+ if (!trimmed || trimmed === '/') {
+ return '/'
+ }
+
+ return `/${trimmed.replace(/^\/+|\/+$/g, '')}/`
+}
+
+export const BASE_PATH = normalizeConfiguredBase(import.meta.env.BASE_URL)
+
+const BASE_PATH_PREFIX = BASE_PATH === '/' ? '' : BASE_PATH.slice(0, -1)
+
+const isExternalPath = (value: string): boolean =>
+ /^(?:[a-z]+:)?\/\//i.test(value) ||
+ value.startsWith('mailto:') ||
+ value.startsWith('tel:') ||
+ value.startsWith('#')
+
+export const withBase = (value: string): string => {
+ if (!value || isExternalPath(value)) {
+ return value
+ }
+
+ const normalizedPath = value === '/' ? '/' : `/${value.replace(/^\/+/, '')}`
+
+ if (BASE_PATH === '/') {
+ return normalizedPath
+ }
+
+ return normalizedPath === '/' ? BASE_PATH : `${BASE_PATH_PREFIX}${normalizedPath}`
+}
+
+export const stripBase = (value: string): string => {
+ if (BASE_PATH === '/' || !value.startsWith(BASE_PATH_PREFIX)) {
+ return value || '/'
+ }
+
+ const strippedPath = value.slice(BASE_PATH_PREFIX.length)
+ return strippedPath || '/'
+}
diff --git a/src/lib/vigotech/calendar.ts b/src/lib/vigotech/calendar.ts
new file mode 100644
index 00000000..4cc13b5d
--- /dev/null
+++ b/src/lib/vigotech/calendar.ts
@@ -0,0 +1,110 @@
+export type CalendarEvent = {
+ id: string
+ title: string
+ start: string
+ end: string | null
+ location: string | null
+ description: string | null
+ htmlLink: string | null
+ allDay: boolean
+}
+
+type GoogleCalendarDate = {
+ date?: string
+ dateTime?: string
+}
+
+type GoogleCalendarItem = {
+ id?: string
+ summary?: string
+ description?: string
+ location?: string
+ htmlLink?: string
+ start?: GoogleCalendarDate
+ end?: GoogleCalendarDate
+}
+
+const CALENDAR_ID = 'orestes.io_fj8ev1vakdnl8l8o6jeljhof1s@group.calendar.google.com'
+const DEFAULT_MAX_RESULTS = 24
+
+const getCalendarApiUrl = (): URL => {
+ const url = new URL(
+ `https://www.googleapis.com/calendar/v3/calendars/${encodeURIComponent(CALENDAR_ID)}/events`,
+ )
+
+ url.searchParams.set('singleEvents', 'true')
+ url.searchParams.set('orderBy', 'startTime')
+ url.searchParams.set('maxResults', String(DEFAULT_MAX_RESULTS))
+ url.searchParams.set('timeMin', new Date().toISOString())
+
+ return url
+}
+
+export const mapGoogleCalendarItem = (item: GoogleCalendarItem): CalendarEvent | null => {
+ const title = item.summary?.trim()
+ const startRaw = item.start?.dateTime ?? item.start?.date
+
+ if (!title || !startRaw) {
+ return null
+ }
+
+ const endRaw = item.end?.dateTime ?? item.end?.date ?? null
+ const allDay = Boolean(item.start?.date && !item.start?.dateTime)
+
+ return {
+ id: item.id ?? `${title}-${startRaw}`,
+ title,
+ start: startRaw,
+ end: endRaw,
+ location: item.location?.trim() || null,
+ description: item.description?.trim() || null,
+ htmlLink: item.htmlLink ?? null,
+ allDay,
+ }
+}
+
+export const fetchGoogleCalendarEvents = async (
+ signal?: AbortSignal,
+): Promise<{ events: CalendarEvent[]; source: 'live' | 'fallback' }> => {
+ const apiKey = process.env.GOOGLE_CALENDAR_API_KEY
+ if (!apiKey) {
+ return {
+ events: [],
+ source: 'fallback',
+ }
+ }
+
+ const url = getCalendarApiUrl()
+ url.searchParams.set('key', apiKey)
+
+ try {
+ const response = await fetch(url, {
+ headers: {
+ accept: 'application/json',
+ },
+ signal,
+ })
+
+ if (!response.ok) {
+ return { events: [], source: 'fallback' }
+ }
+
+ const payload = (await response.json()) as { items?: GoogleCalendarItem[] }
+ const events = (payload.items ?? [])
+ .map(mapGoogleCalendarItem)
+ .filter((item): item is CalendarEvent => Boolean(item))
+
+ return {
+ events,
+ source: 'live',
+ }
+ } catch {
+ return {
+ events: [],
+ source: 'fallback',
+ }
+ }
+}
+
+export const getCalendarIcsUrl = (): string =>
+ 'https://calendar.google.com/calendar/ical/orestes.io_fj8ev1vakdnl8l8o6jeljhof1s%40group.calendar.google.com/public/basic.ics'
diff --git a/src/lib/vigotech/documents.ts b/src/lib/vigotech/documents.ts
new file mode 100644
index 00000000..3849a7c1
--- /dev/null
+++ b/src/lib/vigotech/documents.ts
@@ -0,0 +1,33 @@
+export type DocumentSource = {
+ id: string
+ title: string
+ slug: string
+ url: string
+}
+
+export const documentSources: DocumentSource[] = [
+ {
+ id: 'manifesto',
+ title: 'Manifesto',
+ slug: 'manifesto',
+ url: 'https://raw.githubusercontent.com/VigoTech/documentos/master/manifiesto.md',
+ },
+ {
+ id: 'codigo-conduta',
+ title: 'Codigo de conducta',
+ slug: 'codigo-conduta',
+ url: 'https://raw.githubusercontent.com/VigoTech/documentos/master/codigodeconducta.md',
+ },
+ {
+ id: 'condicions-entrada',
+ title: 'Condicions de entrada',
+ slug: 'condicions-entrada',
+ url: 'https://raw.githubusercontent.com/VigoTech/documentos/master/condicionsentrada.md',
+ },
+ {
+ id: 'codigo-conduta-slack',
+ title: 'Codigo de conducta en Slack',
+ slug: 'codigo-conduta-slack',
+ url: 'https://raw.githubusercontent.com/VigoTech/documentos/master/conducta_slack.md',
+ },
+]
diff --git a/src/lib/vigotech/selectors.ts b/src/lib/vigotech/selectors.ts
new file mode 100644
index 00000000..e3ef06cd
--- /dev/null
+++ b/src/lib/vigotech/selectors.ts
@@ -0,0 +1,47 @@
+import type { CollectionEntry } from 'astro:content'
+
+type VideoEntry = CollectionEntry<'videos'>
+type EventEntry = CollectionEntry<'events'>
+type GroupEntry = CollectionEntry<'groups'>
+
+export const sortVideosByDate = (videos: VideoEntry[]): VideoEntry[] =>
+ [...videos].sort((a, b) => {
+ const aDate = a.data.publishedAt ?? 0
+ const bDate = b.data.publishedAt ?? 0
+ return bDate - aDate
+ })
+
+export const getRecentVideos = (videos: VideoEntry[], amount = 4): VideoEntry[] =>
+ sortVideosByDate(videos).slice(0, amount)
+
+export const getUpcomingEvents = (events: EventEntry[], amount = 3): EventEntry[] => {
+ const now = Date.now()
+ const upcoming = [...events]
+ .filter((event) => event.data.date >= now)
+ .sort((a, b) => a.data.date - b.data.date)
+
+ return upcoming.slice(0, amount)
+}
+
+export const getTopGroupsByLastEvent = (
+ groups: GroupEntry[],
+ events: EventEntry[],
+ amount = 3,
+): GroupEntry[] => {
+ const lastEventByGroup = new Map()
+
+ for (const event of events) {
+ const prev = lastEventByGroup.get(event.data.groupId) ?? 0
+ if (event.data.date > prev) {
+ lastEventByGroup.set(event.data.groupId, event.data.date)
+ }
+ }
+
+ return [...groups]
+ .sort((a, b) => {
+ const aDate = lastEventByGroup.get(a.id) ?? 0
+ const bDate = lastEventByGroup.get(b.id) ?? 0
+ return bDate - aDate
+ })
+ .slice(0, amount)
+}
diff --git a/src/lib/vigotech/socials.ts b/src/lib/vigotech/socials.ts
new file mode 100644
index 00000000..d1b9e6ad
--- /dev/null
+++ b/src/lib/vigotech/socials.ts
@@ -0,0 +1,98 @@
+export type GroupLinkIcon = {
+ key: string
+ icon: string
+ label: string
+}
+
+const SOCIAL_ICON_MAP: Record = {
+ web: { key: 'web', icon: 'lucide:globe', label: 'Web' },
+ website: { key: 'website', icon: 'lucide:globe', label: 'Web' },
+ home: { key: 'home', icon: 'lucide:house', label: 'Inicio' },
+ github: { key: 'github', icon: 'lucide:github', label: 'GitHub' },
+ twitter: { key: 'twitter', icon: 'lucide:twitter', label: 'Twitter' },
+ x: { key: 'x', icon: 'lucide:twitter', label: 'X' },
+ linkedin: { key: 'linkedin', icon: 'lucide:linkedin', label: 'LinkedIn' },
+ youtube: { key: 'youtube', icon: 'lucide:youtube', label: 'YouTube' },
+ instagram: { key: 'instagram', icon: 'lucide:instagram', label: 'Instagram' },
+ telegram: { key: 'telegram', icon: 'lucide:send', label: 'Telegram' },
+ meetup: { key: 'meetup', icon: 'lucide:users', label: 'Meetup' },
+ discord: { key: 'discord', icon: 'lucide:message-circle', label: 'Discord' },
+ twitch: { key: 'twitch', icon: 'lucide:tv', label: 'Twitch' },
+ slack: { key: 'slack', icon: 'lucide:messages-square', label: 'Slack' },
+ facebook: { key: 'facebook', icon: 'lucide:facebook', label: 'Facebook' },
+ tiktok: { key: 'tiktok', icon: 'lucide:music-2', label: 'TikTok' },
+ mastodon: { key: 'mastodon', icon: 'lucide:radio', label: 'Mastodon' },
+ ivoox: { key: 'ivoox', icon: 'lucide:podcast', label: 'iVoox' },
+ maillist: { key: 'maillist', icon: 'lucide:list', label: 'Lista correo' },
+ spotify: { key: 'spotify', icon: 'lucide:music-3', label: 'Spotify' },
+ mail: { key: 'mail', icon: 'lucide:mail', label: 'Email' },
+}
+
+const LINK_PRIORITY = [
+ 'web',
+ 'website',
+ 'meetup',
+ 'github',
+ 'twitter',
+ 'x',
+ 'linkedin',
+ 'youtube',
+ 'instagram',
+ 'telegram',
+ 'discord',
+ 'twitch',
+ 'slack',
+ 'facebook',
+ 'mastodon',
+ 'ivoox',
+ 'maillist',
+ 'mail',
+ 'spotify',
+ 'tiktok',
+]
+
+const UNKNOWN_LINK_ICON: GroupLinkIcon = {
+ key: 'link',
+ icon: 'lucide:link',
+ label: 'Ligazon',
+}
+
+const normalizeLinkKey = (key: string): string => key.trim().toLowerCase()
+
+export const getGroupSocialLinks = (
+ links: Record,
+ limit?: number,
+): Array<{ key: string; href: string; icon: string; label: string }> => {
+ const normalized = Object.entries(links)
+ .filter(([, href]) => typeof href === 'string' && href.length > 0)
+ .map(([key, href]) => ({
+ key,
+ normalizedKey: normalizeLinkKey(key),
+ href,
+ }))
+
+ const rank = (normalizedKey: string): number => {
+ const index = LINK_PRIORITY.indexOf(normalizedKey)
+ return index === -1 ? Number.MAX_SAFE_INTEGER : index
+ }
+
+ const sorted = normalized.sort((a, b) => {
+ const rankDiff = rank(a.normalizedKey) - rank(b.normalizedKey)
+ return rankDiff !== 0 ? rankDiff : a.key.localeCompare(b.key, 'gl')
+ })
+
+ const selected = typeof limit === 'number' ? sorted.slice(0, limit) : sorted
+
+ return selected.map(({ key, normalizedKey, href }) => {
+ const meta = SOCIAL_ICON_MAP[normalizedKey] ?? {
+ ...UNKNOWN_LINK_ICON,
+ label: key,
+ }
+ return {
+ key,
+ href,
+ icon: meta.icon,
+ label: meta.label,
+ }
+ })
+}
diff --git a/src/lib/vigotech/source.ts b/src/lib/vigotech/source.ts
new file mode 100644
index 00000000..72bbe0c1
--- /dev/null
+++ b/src/lib/vigotech/source.ts
@@ -0,0 +1,82 @@
+import { readFile } from 'node:fs/promises'
+import { join } from 'node:path'
+import { fileURLToPath } from 'node:url'
+
+type Json = Record
+
+const localConfigDataDir =
+ process.env.VIGOTECH_CONFIG_DATA_DIR ?? fileURLToPath(new URL('../../../public', import.meta.url))
+
+const generatedDataDir = process.env.VIGOTECH_GENERATED_DATA_DIR ?? localConfigDataDir
+
+const readJson = async (fileName: string, fallback: T, dataDir: string): Promise => {
+ try {
+ const filePath = join(dataDir, fileName)
+ const raw = await readFile(filePath, 'utf8')
+ return JSON.parse(raw) as T
+ } catch {
+ return fallback
+ }
+}
+
+export type VigotechSource = {
+ name?: string
+ links?: Record
+ members?: Record
+}
+
+export type VigotechGenerated = {
+ name?: string
+ links?: Record
+ nextEvent?: Json
+ members?: Record
+}
+
+export type VigotechSources = {
+ source: VigotechSource
+ generated: VigotechGenerated
+ friends: Record
+}
+
+let cache: Promise | null = null
+
+export const loadVigotechSources = (): Promise => {
+ if (!cache) {
+ cache = Promise.all([
+ readJson('vigotech.json', {}, localConfigDataDir),
+ readJson('vigotech-generated.json', {}, generatedDataDir),
+ readJson>('friends.json', {}, localConfigDataDir),
+ ]).then(([source, generated, friends]) => ({
+ source,
+ generated,
+ friends,
+ }))
+ }
+
+ return cache
+}
+
+export const slugify = (value: string): string =>
+ value
+ .normalize('NFKD')
+ .replace(/[\u0300-\u036f]/g, '')
+ .toLowerCase()
+ .replace(/[^a-z0-9]+/g, '-')
+ .replace(/(^-|-$)/g, '')
+
+export const toLocalGroupLogo = (logo: string | null | undefined): string | null => {
+ if (!logo) {
+ return null
+ }
+
+ if (logo.startsWith('/images/groups/')) {
+ return logo
+ }
+
+ const fromUrl = logo.match(/\/images\/([^/?#]+)$/i)?.[1]
+ if (fromUrl) {
+ return `/images/groups/${fromUrl}`
+ }
+
+ return logo
+}
diff --git a/src/pages/[doc].astro b/src/pages/[doc].astro
new file mode 100644
index 00000000..57083ef7
--- /dev/null
+++ b/src/pages/[doc].astro
@@ -0,0 +1,125 @@
+---
+import { getCollection, render } from 'astro:content'
+
+import { LANG } from '../i18n/config'
+import { docPageT } from '../i18n/doc-page'
+import FloatingHeader from '../components/ui/FloatingHeader.astro'
+import BaseLayout from '../layouts/BaseLayout.astro'
+
+const t = docPageT[LANG]
+
+export async function getStaticPaths() {
+ const docs = await getCollection('documents')
+ return docs.map((doc) => ({
+ params: { doc: doc.data.slug },
+ props: { doc },
+ }))
+}
+
+const { doc } = Astro.props
+const { Content } = await render(doc)
+const lead = t.leads[doc.data.slug as keyof typeof t.leads] ?? t.leads.default
+---
+
+
+
+
+
+
+
+
+
+
+
+ menu_book
+ {t.tocLabel}
+
+
+ expand_more
+
+
+
+
+
+
+
+
+
+
+ {t.reportHeading}
+
+
+ {t.reportDescription}
+
+
+
+
+
+
+
diff --git a/src/pages/api/calendar.json.ts b/src/pages/api/calendar.json.ts
new file mode 100644
index 00000000..43fdd59c
--- /dev/null
+++ b/src/pages/api/calendar.json.ts
@@ -0,0 +1,74 @@
+import type { APIRoute } from 'astro'
+import { getCollection } from 'astro:content'
+
+import type { CalendarEvent } from '../../lib/vigotech/calendar'
+import { fetchGoogleCalendarEvents, getCalendarIcsUrl } from '../../lib/vigotech/calendar'
+
+const normalizeTitle = (value: string): string =>
+ value
+ .normalize('NFKD')
+ .replace(/[\u0300-\u036f]/g, '')
+ .toLowerCase()
+ .replace(/\s+/g, ' ')
+ .trim()
+
+const mapContentEvent = (entry: Awaited>>[number]): CalendarEvent => ({
+ id: entry.data.sourceId,
+ title: entry.data.title,
+ start: entry.data.dateISO,
+ end: null,
+ location: entry.data.location,
+ description: entry.data.description,
+ htmlLink: entry.data.link,
+ allDay: false,
+})
+
+const mergeEventsByTitle = (contentEvents: CalendarEvent[], googleEvents: CalendarEvent[]): CalendarEvent[] => {
+ const merged = new Map()
+
+ for (const event of contentEvents) {
+ merged.set(normalizeTitle(event.title), event)
+ }
+
+ for (const event of googleEvents) {
+ merged.set(normalizeTitle(event.title), event)
+ }
+
+ return [...merged.values()].sort(
+ (a, b) => new Date(a.start).getTime() - new Date(b.start).getTime(),
+ )
+}
+
+export const GET: APIRoute = async ({ request }) => {
+ const controller = new AbortController()
+ const timeout = setTimeout(() => controller.abort(), 8000)
+
+ try {
+ const [{ events: googleEvents, source }, contentEntries] = await Promise.all([
+ fetchGoogleCalendarEvents(controller.signal),
+ getCollection('events'),
+ ])
+
+ const contentEvents = contentEntries.map(mapContentEvent)
+ const events = mergeEventsByTitle(contentEvents, googleEvents)
+
+ return new Response(
+ JSON.stringify({
+ source,
+ events,
+ icsUrl: getCalendarIcsUrl(),
+ }),
+ {
+ status: 200,
+ headers: {
+ 'content-type': 'application/json; charset=utf-8',
+ 'cache-control': 'public, max-age=300, s-maxage=300',
+ vary: 'accept, origin',
+ 'x-request-url': request.url,
+ },
+ },
+ )
+ } finally {
+ clearTimeout(timeout)
+ }
+}
diff --git a/src/pages/groups.astro b/src/pages/groups.astro
new file mode 100644
index 00000000..ea9e305a
--- /dev/null
+++ b/src/pages/groups.astro
@@ -0,0 +1,12 @@
+---
+import { getCollection } from 'astro:content'
+
+import GroupsBrowser from '../components/groups/GroupsBrowser.astro'
+import BaseLayout from '../layouts/BaseLayout.astro'
+
+const groups = [...(await getCollection('groups'))].sort((a, b) => a.data.name.localeCompare(b.data.name, 'gl'))
+---
+
+
+
+
diff --git a/src/pages/index.astro b/src/pages/index.astro
new file mode 100644
index 00000000..f59b6cd9
--- /dev/null
+++ b/src/pages/index.astro
@@ -0,0 +1,40 @@
+---
+import { getCollection } from 'astro:content'
+
+import DocumentsSection from '../components/home/DocumentsSection.astro'
+import FriendsSection from '../components/home/FriendsSection.astro'
+import GroupsSection from '../components/home/GroupsSection.astro'
+import HeroSection from '../components/home/HeroSection.astro'
+import CalendarSection from '../components/home/CalendarSection.astro'
+import ConversationSection from '../components/home/ConversationSection.astro'
+import VideosSection from '../components/home/VideosSection.astro'
+import BaseLayout from '../layouts/BaseLayout.astro'
+import { getRecentVideos, getTopGroupsByLastEvent, getUpcomingEvents } from '../lib/vigotech/selectors'
+
+const groups = await getCollection('groups')
+const events = await getCollection('events')
+const videos = await getCollection('videos')
+const docs = await getCollection('documents')
+const friends = await getCollection('friends')
+
+const sortedGroups = [...groups]
+ .filter((group) => !group.data.inactive)
+ .sort((a, b) => a.data.name.localeCompare(b.data.name, 'gl'))
+const upcomingEvents = getUpcomingEvents(events, 20)
+const featuredGroups = getTopGroupsByLastEvent(groups, events, 3)
+const recentVideos = getRecentVideos(videos, 3)
+---
+
+
+
+
+
+
+
+
+
+
diff --git a/src/pages/videos.astro b/src/pages/videos.astro
new file mode 100644
index 00000000..d14d72a2
--- /dev/null
+++ b/src/pages/videos.astro
@@ -0,0 +1,14 @@
+---
+import { getCollection } from 'astro:content'
+
+import VideosBrowser from '../components/videos/VideosBrowser.astro'
+import BaseLayout from '../layouts/BaseLayout.astro'
+import { sortVideosByDate } from '../lib/vigotech/selectors'
+
+const videos = sortVideosByDate(await getCollection('videos'))
+const groups = await getCollection('groups')
+---
+
+
+
+
diff --git a/src/styles/global.css b/src/styles/global.css
new file mode 100644
index 00000000..911c036a
--- /dev/null
+++ b/src/styles/global.css
@@ -0,0 +1,701 @@
+@import 'tailwindcss';
+
+@font-face {
+ font-family: 'Inter';
+ src: url('/fonts/inter-latin.woff2') format('woff2');
+ font-style: normal;
+ font-weight: 100 900;
+ font-display: swap;
+}
+
+@font-face {
+ font-family: 'Instrument Serif';
+ src: url('/fonts/instrument-serif-latin.woff2') format('woff2');
+ font-style: normal;
+ font-weight: 400;
+ font-display: swap;
+}
+
+@font-face {
+ font-family: 'Instrument Serif';
+ src: url('/fonts/instrument-serif-latin-italic.woff2') format('woff2');
+ font-style: italic;
+ font-weight: 400;
+ font-display: swap;
+}
+
+@custom-variant dark (&:where(.dark, .dark *));
+
+@theme {
+ --color-primary: var(--accent);
+ --color-primary-strong: var(--accent-strong);
+ --color-surface: var(--bg);
+ --color-surface-panel: var(--bg-panel);
+ --color-ink: var(--ink);
+ --color-ink-soft: var(--ink-soft);
+ --color-ink-contrast: var(--ink-contrast);
+ --color-ink-soft-contrast: var(--ink-soft-contrast);
+ --color-white: #ffffff;
+
+ --font-sans: var(--font-body);
+ --font-heading: var(--font-heading);
+}
+
+:root {
+ --font-heading: 'Instrument Serif', 'Times New Roman', serif;
+ --font-body: 'Inter', 'Segoe UI', sans-serif;
+
+ --bg: #f1fbff;
+ --bg-elevated: #ffffff;
+ --bg-panel: #eaf5fa;
+ --ink: #131d21;
+ --ink-soft: #586062;
+ --ink-contrast: #f4f8fc;
+ --ink-soft-contrast: #d3dce5;
+ --line: #d9e4e9;
+ --accent: #e84a5f;
+ --accent-strong: #d33b51;
+
+ --shell-width: 1200px;
+}
+
+.dark {
+ --bg: #0b1219;
+ --bg-elevated: #121c27;
+ --bg-panel: #1a2734;
+ --ink: #e7edf4;
+ --ink-soft: #a6b5c4;
+ --ink-contrast: #101820;
+ --ink-soft-contrast: #3f4f60;
+ --line: #2a3b4d;
+ --accent: #e84a5f;
+ --accent-strong: #ff3559;
+}
+
+html,
+body {
+ min-height: 100%;
+}
+
+body {
+ font-family: var(--font-body);
+ background: var(--bg);
+ color: var(--ink);
+}
+
+h1,
+h2,
+h3,
+h4,
+h5,
+h6 {
+ font-family: var(--font-heading);
+}
+
+.vt-shell {
+ margin: 0 auto;
+ width: min(1600px, calc(100% - 1rem));
+}
+
+.vt-content-shell {
+ margin: 0 auto;
+ width: min(var(--shell-width), calc(100% - 1rem));
+}
+
+@media (min-width: 640px) {
+ .vt-shell {
+ width: min(1600px, calc(100% - 3rem));
+ }
+
+ .vt-content-shell {
+ width: min(var(--shell-width), calc(100% - 3rem));
+ }
+}
+
+.vt-card {
+ border: 1px solid var(--line);
+ background: var(--bg-panel);
+ border-radius: 0.75rem;
+}
+
+.vt-chip {
+ border: 1px solid var(--line);
+ background: color-mix(in srgb, var(--bg-elevated) 82%, transparent);
+ color: var(--ink-soft);
+}
+
+.vt-chip[data-active='true'] {
+ background: color-mix(in srgb, var(--accent) 18%, var(--bg-elevated));
+ border-color: color-mix(in srgb, var(--accent) 42%, var(--line));
+ color: var(--ink);
+}
+
+.vt-link {
+ color: var(--accent);
+ text-decoration: underline;
+ text-underline-offset: 3px;
+}
+
+.vt-nav-link {
+ position: relative;
+ font-family: var(--font-heading);
+ font-size: 22px;
+}
+
+.vt-nav-link::after {
+ content: '';
+ position: absolute;
+ left: 0;
+ right: 0;
+ bottom: -0.35rem;
+ height: 2px;
+ border-radius: 999px;
+ background: var(--accent);
+ transform: scaleX(0);
+ transform-origin: center;
+ transition: transform 180ms ease;
+}
+
+.vt-nav-link:hover::after,
+.vt-nav-link[aria-current='page']::after {
+ transform: scaleX(1);
+}
+
+.vt-nav-link[aria-current='page'] {
+ color: var(--accent);
+}
+
+.vt-btn {
+ display: inline-flex;
+ align-items: center;
+ justify-content: center;
+ gap: 0.5rem;
+ border-radius: 0.65rem;
+ padding: 0.65rem 1rem;
+ font-weight: 600;
+}
+
+.primary-gradient {
+ background: linear-gradient(135deg, var(--accent) 0%, var(--accent-strong) 100%);
+}
+
+.glass-nav {
+ backdrop-filter: blur(20px);
+ -webkit-backdrop-filter: blur(20px);
+}
+
+.glass-nav[data-mobile-nav-open='true'] {
+ bottom: 0;
+}
+
+@media (max-width: 399px) {
+ .vt-site-logo {
+ height: 1.25rem;
+ }
+}
+
+[data-page-content][data-overlay-blocked='true'] {
+ pointer-events: none;
+ filter: blur(10px);
+ transition: filter 220ms ease;
+}
+
+.material-symbols-outlined {
+ font-variation-settings:
+ 'FILL' 0,
+ 'wght' 400,
+ 'GRAD' 0,
+ 'opsz' 24;
+}
+
+.vt-btn-sm {
+ padding: 0.4rem 0.75rem;
+ font-size: 0.75rem;
+ border-radius: 4px;
+}
+
+.vt-btn-primary {
+ background: var(--accent);
+ color: #fff;
+}
+
+.vt-btn-primary:hover {
+ background: var(--accent-strong);
+}
+
+.vt-btn-secondary {
+ border: 1px solid var(--line);
+ background: var(--bg-elevated);
+}
+
+.vt-squircle {
+ border-radius: 30%;
+}
+
+.calendar-grid {
+ display: grid;
+ grid-template-columns: repeat(7, minmax(0, 1fr));
+ gap: 0.4rem;
+}
+
+.vt-sticky-host {
+ position: relative;
+}
+
+.vt-sticky-base {
+ visibility: hidden;
+ opacity: 0;
+ pointer-events: none;
+}
+
+.vt-sticky-base * {
+ visibility: hidden !important;
+}
+
+.vt-sticky-spacer {
+ height: 0;
+ flex: none;
+}
+
+.vt-sticky-shell {
+ border-radius: 0;
+ background: transparent;
+ backdrop-filter: none;
+ -webkit-backdrop-filter: none;
+ padding: 0;
+ transition:
+ background-color 180ms ease,
+ border-radius 180ms ease,
+ backdrop-filter 180ms ease,
+ padding 180ms ease,
+ box-shadow 180ms ease;
+}
+
+.vt-sticky-shell[data-floating='true'] {
+ position: fixed;
+ top: calc(6rem - 5px);
+ z-index: 30;
+ pointer-events: auto;
+}
+
+@media (max-width: 639px) {
+ .vt-sticky-shell[data-floating='true'] {
+ top: calc(5.125rem - 5px);
+ }
+}
+
+.vt-sticky-shell[data-scrolled='true'] {
+ border-radius: 1rem;
+ background: color-mix(in srgb, var(--bg) 82%, transparent);
+ backdrop-filter: blur(20px);
+ -webkit-backdrop-filter: blur(20px);
+ padding: 0.75rem;
+ box-shadow: 0 22px 30px -26px rgba(0, 0, 0, 0.5);
+}
+
+.vt-sticky-shell[data-controls-expanded='true'] {
+ background: var(--bg);
+ backdrop-filter: none;
+ -webkit-backdrop-filter: none;
+ box-shadow: none;
+ isolation: isolate;
+ padding: 0.75rem;
+}
+
+.vt-sticky-shell[data-scrolled='false'] {
+ pointer-events: auto;
+}
+
+.vt-sticky-controls {
+ display: flex;
+ flex-direction: column;
+ margin-top: 1.5em;
+ gap: 0.75rem;
+}
+
+.vt-sticky-controls-top {
+ min-width: 0;
+}
+
+.vt-sticky-controls-toggle {
+ height: 2.5rem;
+}
+
+.vt-sticky-controls-panel {
+ display: none;
+}
+
+.vt-sticky-controls[data-controls-expanded='true'] .vt-sticky-controls-panel {
+ display: flex;
+ flex-direction: column;
+ gap: 0.75rem;
+ margin-top: 0.25rem;
+}
+
+@media (min-width: 1024px) {
+ .vt-sticky-controls[data-controls-expanded='true'] .vt-sticky-controls-panel {
+ flex-direction: row;
+ }
+}
+
+.vt-sticky-shell[data-scrolled='true'] .vt-sticky-controls-top {
+ display: flex;
+}
+
+.vt-sticky-shell[data-scrolled='true'] .vt-sticky-controls {
+ margin-top: 0;
+}
+
+@media (min-width: 1024px) {
+ .vt-sticky-controls {
+ flex-direction: row;
+ align-items: center;
+ justify-content: space-between;
+ }
+
+ .vt-sticky-controls-top {
+ display: none;
+ }
+
+ .vt-sticky-controls-panel {
+ display: flex;
+ min-width: 0;
+ flex: 1;
+ flex-direction: row;
+ gap: 1rem;
+ border-radius: 0;
+ background: transparent;
+ padding: 0;
+ box-shadow: none;
+ opacity: 1;
+ pointer-events: auto;
+ transition: none;
+ overflow: visible;
+ margin-top: 0;
+ }
+}
+
+.vt-sticky-compact-title {
+ display: none;
+}
+
+.vt-sticky-shell[data-scrolled='true'] .vt-sticky-heading {
+ display: none;
+}
+
+.vt-sticky-shell[data-scrolled='true'] .vt-sticky-compact-title {
+ display: block;
+ font-size: clamp(1.3rem, 2.2vw, 1.85rem);
+ line-height: 1.05;
+ margin: 0;
+ white-space: nowrap;
+}
+
+.vt-sticky-title-bar {
+ display: none;
+}
+
+.vt-sticky-shell[data-has-controls='false'][data-scrolled='true'] .vt-sticky-title-bar {
+ display: block;
+}
+
+.vt-sticky-heading em,
+.vt-sticky-heading .accent,
+.vt-sticky-heading span.italic,
+.vt-sticky-compact-title em,
+.vt-sticky-compact-title .accent,
+.vt-sticky-compact-title span.italic {
+ color: var(--accent);
+ font-style: italic;
+}
+
+.vt-filter-scroll-wrap {
+ position: relative;
+ min-width: 0;
+ flex: 1;
+}
+
+.vt-filter-list {
+ display: flex;
+ flex-wrap: wrap;
+ align-items: center;
+ gap: 0.5rem;
+}
+
+@media (min-width: 1024px) {
+ .vt-filter-list {
+ flex-wrap: nowrap;
+ overflow-x: auto;
+ padding-right: 2rem;
+ scrollbar-width: none;
+ -ms-overflow-style: none;
+ }
+}
+
+@media (min-width: 1024px) {
+ .vt-filter-list::-webkit-scrollbar {
+ display: none;
+ }
+}
+
+@media (max-width: 1023px) {
+ .vt-filter-scroll-wrap::after {
+ display: none;
+ }
+}
+
+@media (min-width: 1024px) {
+ .vt-filter-scroll-wrap::after {
+ content: '';
+ position: absolute;
+ top: 0;
+ right: 0;
+ bottom: 0;
+ width: 2.5rem;
+ pointer-events: none;
+ background: linear-gradient(
+ 90deg,
+ rgba(0, 0, 0, 0) 0%,
+ color-mix(in srgb, var(--bg) 88%, transparent) 72%
+ );
+ }
+}
+
+.vt-filter-list {
+ scrollbar-width: none;
+ -ms-overflow-style: none;
+}
+
+.vt-filter-chip,
+.vt-filter-input {
+ height: 2.5rem;
+}
+
+.vt-sticky-mobile-overlay {
+ position: fixed;
+ inset: 0;
+ z-index: 25;
+ border: 0;
+ background: color-mix(in srgb, var(--bg) 42%, transparent);
+ opacity: 0;
+ pointer-events: none;
+ transition: opacity 180ms ease;
+}
+
+.vt-sticky-mobile-overlay[data-visible='true'] {
+ opacity: 1;
+ pointer-events: auto;
+}
+
+@media (min-width: 1024px) {
+ .vt-sticky-mobile-overlay {
+ display: none;
+ }
+}
+
+.vt-mobile-nav-panel {
+ display: none;
+ opacity: 0;
+ transition:
+ opacity 180ms ease,
+ transform 180ms ease;
+}
+
+.vt-mobile-nav-panel[data-open='true'] {
+ display: block;
+ opacity: 1;
+ transform: translateY(0);
+ pointer-events: auto;
+}
+
+.vt-mobile-nav-link {
+ font-family: var(--font-heading);
+ border-radius: 1rem;
+ padding: 0.7rem 0.85rem;
+}
+
+.vt-mobile-nav-link[aria-current='page'] {
+ background: color-mix(in srgb, var(--accent) 14%, transparent);
+ color: var(--accent);
+}
+
+.vt-mobile-nav-overlay {
+ position: fixed;
+ inset: 0;
+ z-index: 35;
+ border: 0;
+ background: color-mix(in srgb, var(--bg) 42%, transparent);
+ opacity: 0;
+ pointer-events: none;
+ transition: opacity 180ms ease;
+}
+
+.vt-mobile-nav-overlay[data-open='true'] {
+ opacity: 1;
+ pointer-events: auto;
+}
+
+.doc-page {
+ min-height: max(884px, 100dvh);
+}
+
+.doc-badge {
+ display: inline-block;
+ border-radius: 999px;
+ background: var(--bg-panel);
+ color: #e84a5f;
+ padding: 0.4rem 0.8rem;
+ font-size: 0.68rem;
+ font-weight: 700;
+ text-transform: uppercase;
+ letter-spacing: 0.12em;
+}
+
+.doc-title {
+ margin-top: 1rem;
+ font-family: var(--font-heading);
+ font-size: clamp(2.2rem, 9vw, 3.2rem);
+ line-height: 1.05;
+ font-weight: 700;
+ letter-spacing: -0.03em;
+}
+
+.doc-title em,
+.doc-title .accent,
+.doc-title span {
+ color: #e84a5f;
+}
+
+.doc-lead {
+ margin-top: 1.2rem;
+ max-width: 48ch;
+ font-size: 1.05rem;
+ line-height: 1.55;
+ color: var(--ink-soft);
+}
+
+.doc-toc {
+ overflow: hidden;
+ border-radius: 0.9rem;
+ background: var(--bg-panel);
+}
+
+.doc-toc-summary {
+ display: flex;
+ cursor: pointer;
+ align-items: center;
+ justify-content: space-between;
+ list-style: none;
+ padding: 1rem 1.15rem;
+}
+
+.doc-toc-links {
+ display: flex;
+ flex-direction: column;
+ gap: 0.6rem;
+ padding: 0 1.15rem 1rem;
+}
+
+.doc-toc-link {
+ font-size: 0.9rem;
+ transition: color 180ms ease;
+}
+
+.doc-toc-link-primary {
+ border-left: 3px solid #e84a5f;
+ padding-left: 0.65rem;
+ color: #e84a5f;
+ font-weight: 700;
+}
+
+.doc-toc-link-secondary {
+ padding-left: 0.85rem;
+ color: #64748b;
+}
+
+.doc-toc-link-secondary:hover {
+ color: #e84a5f;
+}
+
+.doc-content {
+ border-radius: 1rem;
+ background: var(--bg-elevated);
+ padding: 1.25rem;
+}
+
+.doc-content-inner {
+ color: var(--ink-soft);
+ line-height: 1.7;
+}
+
+.doc-content-inner h1,
+.doc-content-inner h2,
+.doc-content-inner h3 {
+ color: var(--ink);
+ font-family: var(--font-heading);
+ letter-spacing: -0.02em;
+}
+
+.doc-content-inner h2 {
+ margin-top: 2rem;
+ margin-bottom: 0.9rem;
+ font-size: 1.55rem;
+ display: flex;
+ align-items: center;
+ gap: 0.45rem;
+}
+
+.doc-content-inner h3 {
+ margin-top: 1.6rem;
+ margin-bottom: 0.7rem;
+ font-size: 1.1rem;
+}
+
+.doc-content-inner p,
+.doc-content-inner li {
+ color: var(--ink-soft);
+}
+
+.doc-content-inner ul,
+.doc-content-inner ol {
+ padding-left: 1.1rem;
+}
+
+.doc-content-inner a {
+ color: #e84a5f;
+ text-decoration: underline;
+ text-underline-offset: 3px;
+}
+
+.doc-report {
+ border-radius: 1.4rem;
+ background: var(--bg-panel);
+ padding: 1.5rem;
+}
+
+.doc-report-button {
+ border-radius: 0.8rem;
+ background: linear-gradient(135deg, var(--accent) 0%, var(--accent-strong) 100%);
+ color: white;
+ font-family: var(--font-heading);
+ font-weight: 700;
+ padding: 0.75rem 1rem;
+ box-shadow: 0 24px 32px -6px rgba(177, 31, 59, 0.2);
+}
+
+@media (prefers-reduced-motion: no-preference) {
+ .reveal {
+ opacity: 0;
+ transform: translateY(20px);
+ transition:
+ opacity 640ms cubic-bezier(0.2, 0.8, 0.2, 1),
+ transform 640ms cubic-bezier(0.2, 0.8, 0.2, 1);
+ transition-delay: var(--reveal-delay, 0ms);
+ will-change: opacity, transform;
+ }
+
+ .reveal.is-visible {
+ opacity: 1;
+ transform: translateY(0);
+ }
+}
diff --git a/src/utils/__tests__/sum.test.ts b/src/utils/__tests__/sum.test.ts
new file mode 100644
index 00000000..8b618d68
--- /dev/null
+++ b/src/utils/__tests__/sum.test.ts
@@ -0,0 +1,9 @@
+import { describe, expect, it } from 'vitest'
+
+import { sum } from '../sum'
+
+describe('sum', () => {
+ it('adds two numbers', () => {
+ expect(sum(2, 3)).toBe(5)
+ })
+})
diff --git a/src/utils/sum.ts b/src/utils/sum.ts
new file mode 100644
index 00000000..390f2ad5
--- /dev/null
+++ b/src/utils/sum.ts
@@ -0,0 +1 @@
+export const sum = (a: number, b: number): number => a + b
diff --git a/static/README.md b/static/README.md
deleted file mode 100644
index 3fc50023..00000000
--- a/static/README.md
+++ /dev/null
@@ -1,10 +0,0 @@
-# STATIC
-
-**This directory is not required, you can delete it if you don't want to use it.**
-
-This directory contains your static files.
-Each file inside this directory is mapped to `/`.
-
-Example: `/static/robots.txt` is mapped as `/robots.txt`.
-
-More information about the usage of this directory in [the documentation](https://nuxtjs.org/guide/assets#static).
diff --git a/static/bg.jpg b/static/bg.jpg
deleted file mode 100644
index 01338fa3..00000000
Binary files a/static/bg.jpg and /dev/null differ
diff --git a/static/gcalendar/css/fullcalendar.min.css b/static/gcalendar/css/fullcalendar.min.css
deleted file mode 100644
index 4eab5405..00000000
--- a/static/gcalendar/css/fullcalendar.min.css
+++ /dev/null
@@ -1,5 +0,0 @@
-/*!
- * FullCalendar v3.4.0 Stylesheet
- * Docs & License: https://fullcalendar.io/
- * (c) 2017 Adam Shaw
- */.fc-icon,body .fc{font-size:1em}.fc-button-group,.fc-icon{display:inline-block}.fc-bg,.fc-row .fc-bgevent-skeleton,.fc-row .fc-highlight-skeleton{bottom:0}.fc-icon,.fc-unselectable{-khtml-user-select:none;-webkit-touch-callout:none}.fc{direction:ltr;text-align:left}.fc-rtl{text-align:right}.fc th,.fc-basic-view td.fc-week-number,.fc-icon,.fc-toolbar{text-align:center}.fc-unthemed .fc-content,.fc-unthemed .fc-divider,.fc-unthemed .fc-list-heading td,.fc-unthemed .fc-list-view,.fc-unthemed .fc-popover,.fc-unthemed .fc-row,.fc-unthemed tbody,.fc-unthemed td,.fc-unthemed th,.fc-unthemed thead{border-color:#ddd}.fc-unthemed .fc-popover{background-color:#fff}.fc-unthemed .fc-divider,.fc-unthemed .fc-list-heading td,.fc-unthemed .fc-popover .fc-header{background:#eee}.fc-unthemed .fc-popover .fc-header .fc-close{color:#666}.fc-unthemed td.fc-today{background:#fcf8e3}.fc-highlight{background:#bce8f1;opacity:.3}.fc-bgevent{background:#8fdf82;opacity:.3}.fc-nonbusiness{background:#d7d7d7}.fc-unthemed .fc-disabled-day{background:#d7d7d7;opacity:.3}.ui-widget .fc-disabled-day{background-image:none}.fc-icon{height:1em;line-height:1em;overflow:hidden;font-family:"Courier New",Courier,monospace;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.fc-icon:after{position:relative}.fc-icon-left-single-arrow:after{content:"\02039";font-weight:700;font-size:200%;top:-7%}.fc-icon-right-single-arrow:after{content:"\0203A";font-weight:700;font-size:200%;top:-7%}.fc-icon-left-double-arrow:after{content:"\000AB";font-size:160%;top:-7%}.fc-icon-right-double-arrow:after{content:"\000BB";font-size:160%;top:-7%}.fc-icon-left-triangle:after{content:"\25C4";font-size:125%;top:3%}.fc-icon-right-triangle:after{content:"\25BA";font-size:125%;top:3%}.fc-icon-down-triangle:after{content:"\25BC";font-size:125%;top:2%}.fc-icon-x:after{content:"\000D7";font-size:200%;top:6%}.fc button{-moz-box-sizing:border-box;-webkit-box-sizing:border-box;box-sizing:border-box;margin:0;height:2.1em;padding:0 .6em;font-size:1em;white-space:nowrap;cursor:pointer}.fc button::-moz-focus-inner{margin:0;padding:0}.fc-state-default{border:1px solid;background-color:#f5f5f5;background-image:-moz-linear-gradient(top,#fff,#e6e6e6);background-image:-webkit-gradient(linear,0 0,0 100%,from(#fff),to(#e6e6e6));background-image:-webkit-linear-gradient(top,#fff,#e6e6e6);background-image:-o-linear-gradient(top,#fff,#e6e6e6);background-image:linear-gradient(to bottom,#fff,#e6e6e6);background-repeat:repeat-x;border-color:#e6e6e6 #e6e6e6 #bfbfbf;border-color:rgba(0,0,0,.1) rgba(0,0,0,.1) rgba(0,0,0,.25);color:#333;text-shadow:0 1px 1px rgba(255,255,255,.75);box-shadow:inset 0 1px 0 rgba(255,255,255,.2),0 1px 2px rgba(0,0,0,.05)}.fc-state-default.fc-corner-left{border-top-left-radius:4px;border-bottom-left-radius:4px}.fc-state-default.fc-corner-right{border-top-right-radius:4px;border-bottom-right-radius:4px}.fc button .fc-icon{position:relative;top:-.05em;margin:0 .2em;vertical-align:middle}.fc-state-active,.fc-state-disabled,.fc-state-down,.fc-state-hover{color:#333;background-color:#e6e6e6}.fc-state-hover{color:#333;text-decoration:none;background-position:0 -15px;-webkit-transition:background-position .1s linear;-moz-transition:background-position .1s linear;-o-transition:background-position .1s linear;transition:background-position .1s linear}.fc-state-active,.fc-state-down{background-color:#ccc;background-image:none;box-shadow:inset 0 2px 4px rgba(0,0,0,.15),0 1px 2px rgba(0,0,0,.05)}.fc-state-disabled{cursor:default;background-image:none;opacity:.65;box-shadow:none}.fc-event.fc-draggable,.fc-event[href],.fc-popover .fc-header .fc-close,a[data-goto]{cursor:pointer}.fc .fc-button-group>*{float:left;margin:0 0 0 -1px}.fc .fc-button-group>:first-child{margin-left:0}.fc-popover{position:absolute;box-shadow:0 2px 6px rgba(0,0,0,.15)}.fc-popover .fc-header{padding:2px 4px}.fc-popover .fc-header .fc-title{margin:0 2px}.fc-ltr .fc-popover .fc-header .fc-title,.fc-rtl .fc-popover .fc-header .fc-close{float:left}.fc-ltr .fc-popover .fc-header .fc-close,.fc-rtl .fc-popover .fc-header .fc-title{float:right}.fc-unthemed .fc-popover{border-width:1px;border-style:solid}.fc-unthemed .fc-popover .fc-header .fc-close{font-size:.9em;margin-top:2px}.fc-popover>.ui-widget-header+.ui-widget-content{border-top:0}.fc-divider{border-style:solid;border-width:1px}hr.fc-divider{height:0;margin:0;padding:0 0 2px;border-width:1px 0}.fc-bg table,.fc-row .fc-bgevent-skeleton table,.fc-row .fc-highlight-skeleton table{height:100%}.fc-clear{clear:both}.fc-bg,.fc-bgevent-skeleton,.fc-helper-skeleton,.fc-highlight-skeleton{position:absolute;top:0;left:0;right:0}.fc table{width:100%;box-sizing:border-box;table-layout:fixed;border-collapse:collapse;border-spacing:0;font-size:1em}.fc td,.fc th{border-style:solid;border-width:1px;padding:0;vertical-align:top}.fc td.fc-today{border-style:double}a[data-goto]:hover{text-decoration:underline}.fc .fc-row{border-style:solid;border-width:0}.fc-row table{border-left:0 hidden transparent;border-right:0 hidden transparent;border-bottom:0 hidden transparent}.fc-row:first-child table{border-top:0 hidden transparent}.fc-row{position:relative}.fc-row .fc-bg{z-index:1}.fc-row .fc-bgevent-skeleton td,.fc-row .fc-highlight-skeleton td{border-color:transparent}.fc-row .fc-bgevent-skeleton{z-index:2}.fc-row .fc-highlight-skeleton{z-index:3}.fc-row .fc-content-skeleton{position:relative;z-index:4;padding-bottom:2px}.fc-row .fc-helper-skeleton{z-index:5}.fc-row .fc-content-skeleton td,.fc-row .fc-helper-skeleton td{background:0 0;border-color:transparent;border-bottom:0}.fc-row .fc-content-skeleton tbody td,.fc-row .fc-helper-skeleton tbody td{border-top:0}.fc-scroller{-webkit-overflow-scrolling:touch}.fc-row.fc-rigid,.fc-time-grid-event{overflow:hidden}.fc-scroller>.fc-day-grid,.fc-scroller>.fc-time-grid{position:relative;width:100%}.fc-event{position:relative;display:block;font-size:.85em;line-height:1.3;border-radius:3px;border:1px solid #3a87ad;font-weight:400}.fc-event,.fc-event-dot{background-color:#3a87ad}.fc-event,.fc-event:hover,.ui-widget .fc-event{color:#fff;text-decoration:none}.fc-not-allowed,.fc-not-allowed .fc-event{cursor:not-allowed}.fc-event .fc-bg{z-index:1;background:#fff;opacity:.25}.fc-event .fc-content{position:relative;z-index:2}.fc-event .fc-resizer{position:absolute;z-index:4;display:none}.fc-event.fc-allow-mouse-resize .fc-resizer,.fc-event.fc-selected .fc-resizer{display:block}.fc-event.fc-selected .fc-resizer:before{content:"";position:absolute;z-index:9999;top:50%;left:50%;width:40px;height:40px;margin-left:-20px;margin-top:-20px}.fc-event.fc-selected{z-index:9999!important;box-shadow:0 2px 5px rgba(0,0,0,.2)}.fc-event.fc-selected.fc-dragging{box-shadow:0 2px 7px rgba(0,0,0,.3)}.fc-h-event.fc-selected:before{content:"";position:absolute;z-index:3;top:-10px;bottom:-10px;left:0;right:0}.fc-ltr .fc-h-event.fc-not-start,.fc-rtl .fc-h-event.fc-not-end{margin-left:0;border-left-width:0;padding-left:1px;border-top-left-radius:0;border-bottom-left-radius:0}.fc-ltr .fc-h-event.fc-not-end,.fc-rtl .fc-h-event.fc-not-start{margin-right:0;border-right-width:0;padding-right:1px;border-top-right-radius:0;border-bottom-right-radius:0}.fc-ltr .fc-h-event .fc-start-resizer,.fc-rtl .fc-h-event .fc-end-resizer{cursor:w-resize;left:-1px}.fc-ltr .fc-h-event .fc-end-resizer,.fc-rtl .fc-h-event .fc-start-resizer{cursor:e-resize;right:-1px}.fc-h-event.fc-allow-mouse-resize .fc-resizer{width:7px;top:-1px;bottom:-1px}.fc-h-event.fc-selected .fc-resizer{border-radius:4px;border-width:1px;width:6px;height:6px;border-style:solid;border-color:inherit;background:#fff;top:50%;margin-top:-4px}.fc-ltr .fc-h-event.fc-selected .fc-start-resizer,.fc-rtl .fc-h-event.fc-selected .fc-end-resizer{margin-left:-4px}.fc-ltr .fc-h-event.fc-selected .fc-end-resizer,.fc-rtl .fc-h-event.fc-selected .fc-start-resizer{margin-right:-4px}.fc-day-grid-event{margin:1px 2px 0;padding:0 1px}tr:first-child>td>.fc-day-grid-event{margin-top:2px}.fc-day-grid-event.fc-selected:after{content:"";position:absolute;z-index:1;top:-1px;right:-1px;bottom:-1px;left:-1px;background:#000;opacity:.25}.fc-day-grid-event .fc-content{white-space:nowrap;overflow:hidden}.fc-day-grid-event .fc-time{font-weight:700}.fc-ltr .fc-day-grid-event.fc-allow-mouse-resize .fc-start-resizer,.fc-rtl .fc-day-grid-event.fc-allow-mouse-resize .fc-end-resizer{margin-left:-2px}.fc-ltr .fc-day-grid-event.fc-allow-mouse-resize .fc-end-resizer,.fc-rtl .fc-day-grid-event.fc-allow-mouse-resize .fc-start-resizer{margin-right:-2px}a.fc-more{margin:1px 3px;font-size:.85em;cursor:pointer;text-decoration:none}a.fc-more:hover{text-decoration:underline}.fc-limited{display:none}.fc-day-grid .fc-row{z-index:1}.fc-more-popover{z-index:2;width:220px}.fc-more-popover .fc-event-container{padding:10px}.fc-now-indicator{position:absolute;border:0 solid red}.fc-unselectable{-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;-webkit-tap-highlight-color:transparent}.fc-toolbar.fc-header-toolbar{margin-bottom:1em}.fc-toolbar.fc-footer-toolbar{margin-top:1em}.fc-toolbar .fc-left{float:left}.fc-toolbar .fc-right{float:right}.fc-toolbar .fc-center{display:inline-block}.fc .fc-toolbar>*>*{float:left;margin-left:.75em}.fc .fc-toolbar>*>:first-child{margin-left:0}.fc-toolbar h2{margin:0}.fc-toolbar button{position:relative}.fc-toolbar .fc-state-hover,.fc-toolbar .ui-state-hover{z-index:2}.fc-toolbar .fc-state-down{z-index:3}.fc-toolbar .fc-state-active,.fc-toolbar .ui-state-active{z-index:4}.fc-toolbar button:focus{z-index:5}.fc-view-container *,.fc-view-container :after,.fc-view-container :before{-webkit-box-sizing:content-box;-moz-box-sizing:content-box;box-sizing:content-box}.fc-view,.fc-view>table{position:relative;z-index:1}.fc-basicDay-view .fc-content-skeleton,.fc-basicWeek-view .fc-content-skeleton{padding-bottom:1em}.fc-basic-view .fc-body .fc-row{min-height:4em}.fc-row.fc-rigid .fc-content-skeleton{position:absolute;top:0;left:0;right:0}.fc-day-top.fc-other-month{opacity:.3}.fc-basic-view .fc-day-number,.fc-basic-view .fc-week-number{padding:2px}.fc-basic-view th.fc-day-number,.fc-basic-view th.fc-week-number{padding:0 2px}.fc-ltr .fc-basic-view .fc-day-top .fc-day-number{float:right}.fc-rtl .fc-basic-view .fc-day-top .fc-day-number{float:left}.fc-ltr .fc-basic-view .fc-day-top .fc-week-number{float:left;border-radius:0 0 3px}.fc-rtl .fc-basic-view .fc-day-top .fc-week-number{float:right;border-radius:0 0 0 3px}.fc-basic-view .fc-day-top .fc-week-number{min-width:1.5em;text-align:center;background-color:#f2f2f2;color:grey}.fc-basic-view td.fc-week-number>*{display:inline-block;min-width:1.25em}.fc-agenda-view .fc-day-grid{position:relative;z-index:2}.fc-agenda-view .fc-day-grid .fc-row{min-height:3em}.fc-agenda-view .fc-day-grid .fc-row .fc-content-skeleton{padding-bottom:1em}.fc .fc-axis{vertical-align:middle;padding:0 4px;white-space:nowrap}.fc-ltr .fc-axis{text-align:right}.fc-rtl .fc-axis{text-align:left}.ui-widget td.fc-axis{font-weight:400}.fc-time-grid,.fc-time-grid-container{position:relative;z-index:1}.fc-time-grid{min-height:100%}.fc-time-grid table{border:0 hidden transparent}.fc-time-grid>.fc-bg{z-index:1}.fc-time-grid .fc-slats,.fc-time-grid>hr{position:relative;z-index:2}.fc-time-grid .fc-content-col{position:relative}.fc-time-grid .fc-content-skeleton{position:absolute;z-index:3;top:0;left:0;right:0}.fc-time-grid .fc-business-container{position:relative;z-index:1}.fc-time-grid .fc-bgevent-container{position:relative;z-index:2}.fc-time-grid .fc-highlight-container{z-index:3;position:relative}.fc-time-grid .fc-event-container{position:relative;z-index:4}.fc-time-grid .fc-now-indicator-line{z-index:5}.fc-time-grid .fc-helper-container{position:relative;z-index:6}.fc-time-grid .fc-slats td{height:1.5em;border-bottom:0}.fc-time-grid .fc-slats .fc-minor td{border-top-style:dotted}.fc-time-grid .fc-slats .ui-widget-content{background:0 0}.fc-time-grid .fc-highlight{position:absolute;left:0;right:0}.fc-ltr .fc-time-grid .fc-event-container{margin:0 2.5% 0 2px}.fc-rtl .fc-time-grid .fc-event-container{margin:0 2px 0 2.5%}.fc-time-grid .fc-bgevent,.fc-time-grid .fc-event{position:absolute;z-index:1}.fc-time-grid .fc-bgevent{left:0;right:0}.fc-v-event.fc-not-start{border-top-width:0;padding-top:1px;border-top-left-radius:0;border-top-right-radius:0}.fc-v-event.fc-not-end{border-bottom-width:0;padding-bottom:1px;border-bottom-left-radius:0;border-bottom-right-radius:0}.fc-time-grid-event.fc-selected{overflow:visible}.fc-time-grid-event.fc-selected .fc-bg{display:none}.fc-time-grid-event .fc-content{overflow:hidden}.fc-time-grid-event .fc-time,.fc-time-grid-event .fc-title{padding:0 1px}.fc-time-grid-event .fc-time{font-size:.85em;white-space:nowrap}.fc-time-grid-event.fc-short .fc-content{white-space:nowrap}.fc-time-grid-event.fc-short .fc-time,.fc-time-grid-event.fc-short .fc-title{display:inline-block;vertical-align:top}.fc-time-grid-event.fc-short .fc-time span{display:none}.fc-time-grid-event.fc-short .fc-time:before{content:attr(data-start)}.fc-time-grid-event.fc-short .fc-time:after{content:"\000A0-\000A0"}.fc-time-grid-event.fc-short .fc-title{font-size:.85em;padding:0}.fc-time-grid-event.fc-allow-mouse-resize .fc-resizer{left:0;right:0;bottom:0;height:8px;overflow:hidden;line-height:8px;font-size:11px;font-family:monospace;text-align:center;cursor:s-resize}.fc-time-grid-event.fc-allow-mouse-resize .fc-resizer:after{content:"="}.fc-time-grid-event.fc-selected .fc-resizer{border-radius:5px;border-width:1px;width:8px;height:8px;border-style:solid;border-color:inherit;background:#fff;left:50%;margin-left:-5px;bottom:-5px}.fc-time-grid .fc-now-indicator-line{border-top-width:1px;left:0;right:0}.fc-time-grid .fc-now-indicator-arrow{margin-top:-5px}.fc-ltr .fc-time-grid .fc-now-indicator-arrow{left:0;border-width:5px 0 5px 6px;border-top-color:transparent;border-bottom-color:transparent}.fc-rtl .fc-time-grid .fc-now-indicator-arrow{right:0;border-width:5px 6px 5px 0;border-top-color:transparent;border-bottom-color:transparent}.fc-event-dot{display:inline-block;width:10px;height:10px;border-radius:5px}.fc-rtl .fc-list-view{direction:rtl}.fc-list-view{border-width:1px;border-style:solid}.fc .fc-list-table{table-layout:auto}.fc-list-table td{border-width:1px 0 0;padding:8px 14px}.fc-list-table tr:first-child td{border-top-width:0}.fc-list-heading{border-bottom-width:1px}.fc-list-heading td{font-weight:700}.fc-ltr .fc-list-heading-main{float:left}.fc-ltr .fc-list-heading-alt,.fc-rtl .fc-list-heading-main{float:right}.fc-rtl .fc-list-heading-alt{float:left}.fc-list-item.fc-has-url{cursor:pointer}.fc-list-item:hover td{background-color:#f5f5f5}.fc-list-item-marker,.fc-list-item-time{white-space:nowrap;width:1px}.fc-ltr .fc-list-item-marker{padding-right:0}.fc-rtl .fc-list-item-marker{padding-left:0}.fc-list-item-title a{text-decoration:none;color:inherit}.fc-list-item-title a[href]:hover{text-decoration:underline}.fc-list-empty-wrap2{position:absolute;top:0;left:0;right:0;bottom:0}.fc-list-empty-wrap1{width:100%;height:100%;display:table}.fc-list-empty{display:table-cell;vertical-align:middle;text-align:center}.fc-unthemed .fc-list-empty{background-color:#eee}
\ No newline at end of file
diff --git a/static/gcalendar/css/fullcalendar.print.min.css b/static/gcalendar/css/fullcalendar.print.min.css
deleted file mode 100644
index 8b6cdac8..00000000
--- a/static/gcalendar/css/fullcalendar.print.min.css
+++ /dev/null
@@ -1,5 +0,0 @@
-/*!
- * FullCalendar v3.4.0 Print Stylesheet
- * Docs & License: https://fullcalendar.io/
- * (c) 2017 Adam Shaw
- */.fc-bg,.fc-bgevent-container,.fc-bgevent-skeleton,.fc-business-container,.fc-event .fc-resizer,.fc-helper-container,.fc-helper-skeleton,.fc-highlight-container,.fc-highlight-skeleton{display:none}.fc tbody .fc-row,.fc-time-grid{min-height:0!important}.fc-time-grid .fc-event.fc-not-end:after,.fc-time-grid .fc-event.fc-not-start:before{content:"..."}.fc{max-width:100%!important}.fc-event{background:#fff!important;color:#000!important;page-break-inside:avoid}.fc hr,.fc tbody,.fc td,.fc th,.fc thead,.fc-row{border-color:#ccc!important;background:#fff!important}.fc tbody .fc-row{height:auto!important}.fc tbody .fc-row .fc-content-skeleton{position:static;padding-bottom:0!important}.fc tbody .fc-row .fc-content-skeleton tbody tr:last-child td{padding-bottom:1em}.fc tbody .fc-row .fc-content-skeleton table{height:1em}.fc-more,.fc-more-cell{display:none!important}.fc tr.fc-limited{display:table-row!important}.fc td.fc-limited{display:table-cell!important}.fc-agenda-view .fc-axis,.fc-popover{display:none}.fc-slats,.fc-time-grid hr{display:none!important}.fc button,.fc-button-group,.fc-time-grid .fc-event .fc-time span{display:none}.fc-time-grid .fc-content-skeleton{position:static}.fc-time-grid .fc-content-skeleton table{height:4em}.fc-time-grid .fc-event-container{margin:0!important}.fc-time-grid .fc-event{position:static!important;margin:3px 2px!important}.fc-time-grid .fc-event.fc-not-end{border-bottom-width:1px!important}.fc-time-grid .fc-event.fc-not-start{border-top-width:1px!important}.fc-time-grid .fc-event .fc-time{white-space:normal!important}.fc-time-grid .fc-event .fc-time:after{content:attr(data-full)}.fc-day-grid-container,.fc-scroller,.fc-time-grid-container{overflow:visible!important;height:auto!important}.fc-row{border:0!important;margin:0!important}
\ No newline at end of file
diff --git a/static/gcalendar/css/fullcalendar.vigotech.css b/static/gcalendar/css/fullcalendar.vigotech.css
deleted file mode 100644
index 9acfdd61..00000000
--- a/static/gcalendar/css/fullcalendar.vigotech.css
+++ /dev/null
@@ -1,49 +0,0 @@
-@font-face {
- font-family: 'Raleway';
- font-style: normal;
- font-weight: 400;
- src: local("Raleway"), local("Raleway-Regular"), url(https://fonts.gstatic.com/s/raleway/v11/yQiAaD56cjx1AooMTSghGfY6323mHUZFJMgTvxaG2iE.woff2) format("woff2");
- unicode-range: U+0100-024F, U+1E00-1EFF, U+20A0-20AB, U+20AD-20CF, U+2C60-2C7F, U+A720-A7FF; }
-/* latin */
-@font-face {
- font-family: 'Raleway';
- font-style: normal;
- font-weight: 400;
- src: local("Raleway"), local("Raleway-Regular"), url(https://fonts.gstatic.com/s/raleway/v11/0dTEPzkLWceF7z0koJaX1A.woff2) format("woff2");
- unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2212, U+2215; }
-body {
- margin: 10px !important; }
-
-* {
- font-family: "Raleway", Arial sans-serif; }
-
-.fc-event {
- background: #ff4260;
- border: 0;
- font-family: "Raleway", Arial sans-serif; }
- .fc-event .fc-title {
- font-size: 14px;
- padding: 2px 5px;
- display: block;
- white-space: normal;
- font-weight: bold; }
-
-.fc-event-dot {
- background: #ff4260; }
-
-.fc-list-item-title {
- font-size: 18px; }
-
-.fc-list-heading-main {
- font-size: 12px; }
-
-.fc td.fc-today {
- background: #ffdbe1; }
-.fc th.fc-day-header {
- padding: 5px 10px;
- background: #ff4260;
- color: #FFF; }
-.fc td.fc-sun {
- background: #DDDDDD; }
-
-/*# sourceMappingURL=fullcalendar.vigotech.css.map */
diff --git a/static/gcalendar/css/fullcalendar.vigotech.css.map b/static/gcalendar/css/fullcalendar.vigotech.css.map
deleted file mode 100644
index 160d7bac..00000000
--- a/static/gcalendar/css/fullcalendar.vigotech.css.map
+++ /dev/null
@@ -1,7 +0,0 @@
-{
-"version": 3,
-"mappings": "AAAA,UAMC;EALC,WAAW,EAAE,SAAS;EACtB,UAAU,EAAE,MAAM;EAClB,WAAW,EAAE,GAAG;EAChB,GAAG,EAAE,0JAA0J;EAC/J,aAAa,EAAE,4EAA4E;AAG7F,WAAW;AACX,UAMC;EALC,WAAW,EAAE,SAAS;EACtB,UAAU,EAAE,MAAM;EAClB,WAAW,EAAE,GAAG;EAChB,GAAG,EAAE,qIAAqI;EAC1I,aAAa,EAAE,qGAAqG;ACdtH,IAAK;EACH,MAAM,EAAE,eAAe;;AAGzB,CAAE;EACA,WAAW,ECiBO,2BAAU;;ADd9B,SAAU;EACR,UAAU,ECMQ,OAAO;EDLzB,MAAM,EAAC,CAAC;EACR,WAAW,ECWO,2BAAU;EDT5B,mBAAU;IACR,SAAS,EAAE,IAAI;IACf,OAAO,EAAE,OAAO;IAChB,OAAO,EAAE,KAAK;IACd,WAAW,EAAE,MAAM;IACnB,WAAW,EAAE,IAAI;;AAIrB,aAAc;EACZ,UAAU,ECRQ,OAAO;;ADW3B,mBAAoB;EAClB,SAAS,EAAE,IAAI;;AAGjB,qBAAsB;EACpB,SAAS,EAAE,IAAI;;AAKb,eAAW;EACT,UAAU,EAAE,OAA4B;AAK1C,oBAAgB;EACd,OAAO,EAAE,QAAQ;EACjB,UAAU,EC7BI,OAAO;ED8BrB,KAAK,ECrCS,IAAI;AD0CpB,aAAS;EACP,UAAU,ECjDI,OAAO",
-"sources": ["../scss/_fontface.scss","../scss/_calendar.scss","../scss/_variables.scss"],
-"names": [],
-"file": "fullcalendar.vigotech.css"
-}
\ No newline at end of file
diff --git a/static/gcalendar/gcal.html b/static/gcalendar/gcal.html
deleted file mode 100644
index 5b2aefe8..00000000
--- a/static/gcalendar/gcal.html
+++ /dev/null
@@ -1,93 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-loading...
-
-
-
-
-
diff --git a/static/gcalendar/js/fullcalendar.min.js b/static/gcalendar/js/fullcalendar.min.js
deleted file mode 100644
index 76e1d438..00000000
--- a/static/gcalendar/js/fullcalendar.min.js
+++ /dev/null
@@ -1,10 +0,0 @@
-/*!
- * FullCalendar v3.4.0
- * Docs & License: https://fullcalendar.io/
- * (c) 2017 Adam Shaw
- */
-!function(t){"function"==typeof define&&define.amd?define(["jquery","moment"],t):"object"==typeof exports?module.exports=t(require("jquery"),require("moment")):t(jQuery,moment)}(function(t,e){function n(t){return it(t,Qt)}function i(t,e){e.left&&t.css({"border-left-width":1,"margin-left":e.left-1}),e.right&&t.css({"border-right-width":1,"margin-right":e.right-1})}function r(t){t.css({"margin-left":"","margin-right":"","border-left-width":"","border-right-width":""})}function s(){t("body").addClass("fc-not-allowed")}function o(){t("body").removeClass("fc-not-allowed")}function a(e,n,i){var r=Math.floor(n/e.length),s=Math.floor(n-r*(e.length-1)),o=[],a=[],u=[],h=0;l(e),e.each(function(n,i){var l=n===e.length-1?s:r,c=t(i).outerHeight(!0);c *").each(function(e,i){var r=t(i).outerWidth();r>n&&(n=r)}),n++,e.width(n),n}function h(t,e){var n,i=t.add(e);return i.css({position:"relative",left:-1}),n=t.outerHeight()-e.outerHeight(),i.css({position:"",left:""}),n}function c(e){var n=e.css("position"),i=e.parents().filter(function(){var e=t(this);return/(auto|scroll)/.test(e.css("overflow")+e.css("overflow-y")+e.css("overflow-x"))}).eq(0);return"fixed"!==n&&i.length?i:t(e[0].ownerDocument||document)}function d(t,e){var n=t.offset(),i=n.left-(e?e.left:0),r=n.top-(e?e.top:0);return{left:i,right:i+t.outerWidth(),top:r,bottom:r+t.outerHeight()}}function f(t,e){var n=t.offset(),i=p(t),r=n.left+w(t,"border-left-width")+i.left-(e?e.left:0),s=n.top+w(t,"border-top-width")+i.top-(e?e.top:0);return{left:r,right:r+t[0].clientWidth,top:s,bottom:s+t[0].clientHeight}}function g(t,e){var n=t.offset(),i=n.left+w(t,"border-left-width")+w(t,"padding-left")-(e?e.left:0),r=n.top+w(t,"border-top-width")+w(t,"padding-top")-(e?e.top:0);return{left:i,right:i+t.width(),top:r,bottom:r+t.height()}}function p(t){var e,n=t[0].offsetWidth-t[0].clientWidth,i=t[0].offsetHeight-t[0].clientHeight;return n=v(n),i=v(i),e={left:0,right:0,top:0,bottom:i},m()&&"rtl"==t.css("direction")?e.left=n:e.right=n,e}function v(t){return t=Math.max(0,t),t=Math.round(t)}function m(){return null===Xt&&(Xt=y()),Xt}function y(){var e=t("").css({position:"absolute",top:-1e3,left:0,border:0,padding:0,overflow:"scroll",direction:"rtl"}).appendTo("body"),n=e.children(),i=n.offset().left>e.offset().left;return e.remove(),i}function w(t,e){return parseFloat(t.css(e))||0}function S(t){return 1==t.which&&!t.ctrlKey}function b(t){var e=t.originalEvent.touches;return e&&e.length?e[0].pageX:t.pageX}function E(t){var e=t.originalEvent.touches;return e&&e.length?e[0].pageY:t.pageY}function D(t){return/^touch/.test(t.type)}function T(t){t.addClass("fc-unselectable").on("selectstart",H)}function C(t){t.removeClass("fc-unselectable").off("selectstart",H)}function H(t){t.preventDefault()}function R(t,e){var n={left:Math.max(t.left,e.left),right:Math.min(t.right,e.right),top:Math.max(t.top,e.top),bottom:Math.min(t.bottom,e.bottom)};return n.leftl&&o=l?(n=o.clone(),r=!0):(n=l.clone(),r=!1),a<=u?(i=a.clone(),s=!0):(i=u.clone(),s=!1),{start:n,end:i,isStart:r,isEnd:s}}function F(t,n){return e.duration({days:t.clone().stripTime().diff(n.clone().stripTime(),"days"),ms:t.time()-n.time()})}function A(t,n){return e.duration({days:t.clone().stripTime().diff(n.clone().stripTime(),"days")})}function G(t,n,i){return e.duration(Math.round(t.diff(n,i,!0)),i)}function V(t,e){var n,i,r;for(n=0;n=1&&vt(r)));n++);return i}function O(t,e){var n=V(t);return"week"===n&&"object"==typeof e&&e.days&&(n="day"),n}function P(t,n,i){return null!=i?i.diff(n,t,!0):e.isDuration(n)?n.as(t):n.end.diff(n.start,t,!0)}function _(t,e,n){var i;return tt(n)?(e-t)/n:(i=n.asMonths(),Math.abs(i)>=1&&vt(i)?e.diff(t,"months",!0)/i:e.diff(t,"days",!0)/n.asDays())}function W(t,e){var n,i;return tt(t)||tt(e)?t/e:(n=t.asMonths(),i=e.asMonths(),Math.abs(n)>=1&&vt(n)&&Math.abs(i)>=1&&vt(i)?n/i:t.asDays()/e.asDays())}function Y(t,n){var i;return tt(t)?e.duration(t*n):(i=t.asMonths(),Math.abs(i)>=1&&vt(i)?e.duration({months:i*n}):e.duration({days:t.asDays()*n}))}function q(t){return{start:t.start.clone(),end:t.end.clone()}}function U(t,e){return t=q(t),e.start&&(t.start=j(t.start,e)),e.end&&(t.end=K(t.end,e.end)),t}function j(t,e){return t=t.clone(),e.start&&(t=J(t,e.start)),e.end&&t>=e.end&&(t=e.end.clone().subtract(1)),t}function Z(t,e){return(!e.start||t>=e.start)&&(!e.end||t=e.start)&&(!e.end||t.start=e.start)&&(!e.end||t.end<=e.end)}function X(t,e){return(t.start&&e.start&&t.start.isSame(e.start)||!t.start&&!e.start)&&(t.end&&e.end&&t.end.isSame(e.end)||!t.end&&!e.end)}function K(t,e){return(t.isBefore(e)?t:e).clone()}function J(t,e){return(t.isAfter(e)?t:e).clone()}function tt(t){return Boolean(t.hours()||t.minutes()||t.seconds()||t.milliseconds())}function et(t){return"[object Date]"===Object.prototype.toString.call(t)||t instanceof Date}function nt(t){return/^\d+\:\d+(?:\:\d+\.?(?:\d{3})?)?$/.test(t)}function it(t,e){var n,i,r,s,o,a,l={};if(e)for(n=0;n=0;s--)if("object"==typeof(o=t[s][i]))r.unshift(o);else if(void 0!==o){l[i]=o;break}r.length&&(l[i]=it(r))}for(n=t.length-1;n>=0;n--){a=t[n];for(i in a)i in l||(l[i]=a[i])}return l}function rt(t){var e=function(){};return e.prototype=t,new e}function st(t,e){for(var n in t)ot(t,n)&&(e[n]=t[n])}function ot(t,e){return te.call(t,e)}function at(e){return/undefined|null|boolean|number|string/.test(t.type(e))}function lt(e,n,i){if(t.isFunction(e)&&(e=[e]),e){var r,s;for(r=0;r /g,">").replace(/'/g,"'").replace(/"/g,""").replace(/\n/g," ")}function ct(t){return t.replace(/&.*?;/g,"")}function dt(e){var n=[];return t.each(e,function(t,e){null!=e&&n.push(t+":"+e)}),n.join(";")}function ft(e){var n=[];return t.each(e,function(t,e){null!=e&&n.push(t+'="'+ht(e)+'"')}),n.join(" ")}function gt(t){return t.charAt(0).toUpperCase()+t.slice(1)}function pt(t,e){return t-e}function vt(t){return t%1==0}function mt(t,e){var n=t[e];return function(){return n.apply(t,arguments)}}function yt(t,e,n){var i,r,s,o,a,l=function(){var u=+new Date-o;u=t.leftCol)return!0;return!1}function Ft(t,e){return t.leftCol-e.leftCol}function At(t){var e,n,i,r=[];for(e=0;ee.top&&t.top"),g.append(o("left")).append(o("right")).append(o("center")).append('
')):s()}function s(){g&&(g.remove(),g=f.el=null)}function o(i){var r=t('
'),s=n.layout[i],o=e.opt("customButtons")||{},a=e.opt("buttonText")||{};return s&&t.each(s.split(" "),function(n){var i,s=t(),l=!0;t.each(this.split(","),function(n,i){var r,u,h,c,d,f,g,m,y,w;"title"==i?(s=s.add(t(" ")),l=!1):((r=o[i])?(h=function(t){r.click&&r.click.call(w[0],t)},c="",d=r.text):(u=e.getViewSpec(i))?(h=function(){e.changeView(i)},v.push(i),c=u.buttonTextOverride,d=u.buttonTextDefault):e[i]&&(h=function(){e[i]()},c=(e.overrides.buttonText||{})[i],d=a[i]),h&&(f=r?r.themeIcon:e.opt("themeButtonIcons")[i],g=r?r.icon:e.opt("buttonIcons")[i],m=c?ht(c):f&&e.opt("theme")?" ":g&&!e.opt("theme")?" ":ht(d),y=["fc-"+i+"-button",p+"-button",p+"-state-default"],w=t(''+m+" ").click(function(t){w.hasClass(p+"-state-disabled")||(h(t),(w.hasClass(p+"-state-active")||w.hasClass(p+"-state-disabled"))&&w.removeClass(p+"-state-hover"))}).mousedown(function(){w.not("."+p+"-state-active").not("."+p+"-state-disabled").addClass(p+"-state-down")}).mouseup(function(){w.removeClass(p+"-state-down")}).hover(function(){w.not("."+p+"-state-active").not("."+p+"-state-disabled").addClass(p+"-state-hover")},function(){w.removeClass(p+"-state-hover").removeClass(p+"-state-down")}),s=s.add(w)))}),l&&s.first().addClass(p+"-corner-left").end().last().addClass(p+"-corner-right").end(),s.length>1?(i=t("
"),l&&i.addClass("fc-button-group"),i.append(s),r.append(i)):r.append(s)}),r}function a(t){g&&g.find("h2").text(t)}function l(t){g&&g.find(".fc-"+t+"-button").addClass(p+"-state-active")}function u(t){g&&g.find(".fc-"+t+"-button").removeClass(p+"-state-active")}function h(t){g&&g.find(".fc-"+t+"-button").prop("disabled",!0).addClass(p+"-state-disabled")}function c(t){g&&g.find(".fc-"+t+"-button").prop("disabled",!1).removeClass(p+"-state-disabled")}function d(){return v}var f=this;f.setToolbarOptions=i,f.render=r,f.removeElement=s,f.updateTitle=a,f.activateButton=l,f.deactivateButton=u,f.disableButton=h,f.enableButton=c,f.getViewsWithButtons=d,f.el=null;var g,p,v=[]}function Yt(e){t.each(Me,function(t,n){null==e[t]&&(e[t]=n(e))})}function qt(t){return e.localeData(t)||e.localeData("en")}function Ut(){function n(t,e){return!q.opt("lazyFetching")||s(t,e)?o(t,e):he.resolve(Z)}function i(){Z=r(K),q.trigger("eventsReset",Z)}function r(t){var e,n,i=[];for(e=0;eU&&i.push(n);return i}function s(t,e){return!U||tj}function o(t,e){return U=t,j=e,a()}function a(){return u(Q,"reset")}function l(t){return u(b(t))}function u(t,e){var n,i;for("reset"===e?K=[]:"add"!==e&&(K=C(K,t)),n=0;ns&&(!l[o]||u.isSame(h,l[o]))&&(o-1!==s||"."!==f[o]);o--)v=f[o]+v;for(a=s;a<=o;a++)m+=f[a],y+=g[a];return(m||y)&&(w=r?y+i+m:m+i+y),d(p+w+v)}function r(t){return S[t]||(S[t]=s(t))}function s(t){var e=o(t);return{fakeFormatString:l(e),sameUnits:u(e)}}function o(t){for(var e,n=[],i=/\[([^\]]*)\]|\(([^\)]*)\)|(LTS|LT|(\w)\4*o?)|([^\w\[\(]+)/g;e=i.exec(t);)e[1]?n.push.apply(n,a(e[1])):e[2]?n.push({maybe:o(e[2])}):e[3]?n.push({token:e[3]}):e[5]&&n.push.apply(n,a(e[5]));return n}function a(t){return". "===t?["."," "]:[t]}function l(t){var e,n,i=[];for(e=0;er.value)&&(r=i);return r?r.unit:null}Zt.formatDate=t,Zt.formatRange=n,Zt.oldMomentFormat=e,Zt.queryMostGranularFormatUnit=f;var g="\v",p="",v="",m=new RegExp(v+"([^"+v+"]*)"+v,"g"),y={t:function(t){return e(t,"a").charAt(0)},T:function(t){return e(t,"A").charAt(0)}},w={Y:{value:1,unit:"year"},M:{value:2,unit:"month"},W:{value:3,unit:"week"},w:{value:3,unit:"week"},D:{value:4,unit:"day"},d:{value:4,unit:"day"}},S={}}();var oe=Zt.formatDate,ae=Zt.formatRange,le=Zt.oldMomentFormat;Zt.Class=bt,bt.extend=function(){var t,e,n=arguments.length;for(t=0;t=0;e--)n=i[e],n.namespace!==t.namespace||"add"!==n.type&&"remove"!==n.type||i.splice(e,1);"destroy"===t.type?i.length&&(n=i[i.length-1],n.namespace===t.namespace&&("init"===n.type?(r=!1,i.pop()):"destroy"===n.type&&(r=!1))):"init"===t.type&&i.length&&(n=i[i.length-1],n.namespace===t.namespace&&"init"===n.type&&i.pop())}return r&&i.push(t),r}});Zt.RenderQueue=de;var fe=Zt.EmitterMixin={on:function(e,n){return t(this).on(e,this._prepareIntercept(n)),this},one:function(e,n){return t(this).one(e,this._prepareIntercept(n)),this},_prepareIntercept:function(e){var n=function(t,n){return e.apply(n.context||this,n.args||[])};return e.guid||(e.guid=t.guid++),n.guid=e.guid,n},
-off:function(e,n){return t(this).off(e,n),this},trigger:function(e){var n=Array.prototype.slice.call(arguments,1);return t(this).triggerHandler(e,{args:n}),this},triggerWith:function(e,n,i){return t(this).triggerHandler(e,{context:n,args:i}),this}},ge=Zt.ListenerMixin=function(){var e=0;return{listenerId:null,listenTo:function(e,n,i){if("object"==typeof n)for(var r in n)n.hasOwnProperty(r)&&this.listenTo(e,r,n[r]);else"string"==typeof n&&e.on(n+"."+this.getListenerNamespace(),t.proxy(i,this))},stopListeningTo:function(t,e){t.off((e||"")+"."+this.getListenerNamespace())},getListenerNamespace:function(){return null==this.listenerId&&(this.listenerId=e++),"_listener"+this.listenerId}}}(),pe=bt.extend(ge,{isHidden:!0,options:null,el:null,margin:10,constructor:function(t){this.options=t||{}},show:function(){this.isHidden&&(this.el||this.render(),this.el.show(),this.position(),this.isHidden=!1,this.trigger("show"))},hide:function(){this.isHidden||(this.el.hide(),this.isHidden=!0,this.trigger("hide"))},render:function(){var e=this,n=this.options;this.el=t('
').addClass(n.className||"").css({top:0,left:0}).append(n.content).appendTo(n.parentEl),this.el.on("click",".fc-close",function(){e.hide()}),n.autoHide&&this.listenTo(t(document),"mousedown",this.documentMousedown)},documentMousedown:function(e){this.el&&!t(e.target).closest(this.el).length&&this.hide()},removeElement:function(){this.hide(),this.el&&(this.el.remove(),this.el=null),this.stopListeningTo(t(document),"mousedown")},position:function(){var e,n,i,r,s,o=this.options,a=this.el.offsetParent().offset(),l=this.el.outerWidth(),u=this.el.outerHeight(),h=t(window),d=c(this.el);r=o.top||0,s=void 0!==o.left?o.left:void 0!==o.right?o.right-l:0,d.is(window)||d.is(document)?(d=h,e=0,n=0):(i=d.offset(),e=i.top,n=i.left),e+=h.scrollTop(),n+=h.scrollLeft(),!1!==o.viewportConstrain&&(r=Math.min(r,e+d.outerHeight()-u-this.margin),r=Math.max(r,e+this.margin),s=Math.min(s,n+d.outerWidth()-l-this.margin),s=Math.max(s,n+this.margin)),this.el.css({top:r-a.top,left:s-a.left})},trigger:function(t){this.options[t]&&this.options[t].apply(this,Array.prototype.slice.call(arguments,1))}}),ve=Zt.CoordCache=bt.extend({els:null,forcedOffsetParentEl:null,origin:null,boundingRect:null,isHorizontal:!1,isVertical:!1,lefts:null,rights:null,tops:null,bottoms:null,constructor:function(e){this.els=t(e.els),this.isHorizontal=e.isHorizontal,this.isVertical=e.isVertical,this.forcedOffsetParentEl=e.offsetParent?t(e.offsetParent):null},build:function(){var t=this.forcedOffsetParentEl;!t&&this.els.length>0&&(t=this.els.eq(0).offsetParent()),this.origin=t?t.offset():null,this.boundingRect=this.queryBoundingRect(),this.isHorizontal&&this.buildElHorizontals(),this.isVertical&&this.buildElVerticals()},clear:function(){this.origin=null,this.boundingRect=null,this.lefts=null,this.rights=null,this.tops=null,this.bottoms=null},ensureBuilt:function(){this.origin||this.build()},buildElHorizontals:function(){var e=[],n=[];this.els.each(function(i,r){var s=t(r),o=s.offset().left,a=s.outerWidth();e.push(o),n.push(o+a)}),this.lefts=e,this.rights=n},buildElVerticals:function(){var e=[],n=[];this.els.each(function(i,r){var s=t(r),o=s.offset().top,a=s.outerHeight();e.push(o),n.push(o+a)}),this.tops=e,this.bottoms=n},getHorizontalIndex:function(t){this.ensureBuilt();var e,n=this.lefts,i=this.rights,r=n.length;for(e=0;e=n[e]&&t=n[e]&&t0&&(t=c(this.els.eq(0)),!t.is(document))?f(t):null},isPointInBounds:function(t,e){return this.isLeftInBounds(t)&&this.isTopInBounds(e)},isLeftInBounds:function(t){return!this.boundingRect||t>=this.boundingRect.left&&t=this.boundingRect.top&&t=i*i&&this.handleDistanceSurpassed(t),this.isDragging&&this.handleDrag(e,n,t)},handleDrag:function(t,e,n){this.trigger("drag",t,e,n),this.updateAutoScroll(n)},endDrag:function(t){this.isDragging&&(this.isDragging=!1,this.handleDragEnd(t))},handleDragEnd:function(t){this.trigger("dragEnd",t)},startDelay:function(t){var e=this;this.delay?this.delayTimeoutId=setTimeout(function(){e.handleDelayEnd(t)},this.delay):this.handleDelayEnd(t)},handleDelayEnd:function(t){this.isDelayEnded=!0,this.isDistanceSurpassed&&this.startDrag(t)},handleDistanceSurpassed:function(t){this.isDistanceSurpassed=!0,this.isDelayEnded&&this.startDrag(t)},handleTouchMove:function(t){this.isDragging&&this.shouldCancelTouchScroll&&t.preventDefault(),this.handleMove(t)},handleMouseMove:function(t){this.handleMove(t)},handleTouchScroll:function(t){this.isDragging&&!this.scrollAlwaysKills||this.endInteraction(t,!0)},trigger:function(t){this.options[t]&&this.options[t].apply(this,Array.prototype.slice.call(arguments,1)),this["_"+t]&&this["_"+t].apply(this,Array.prototype.slice.call(arguments,1))}});me.mixin({isAutoScroll:!1,scrollBounds:null,scrollTopVel:null,scrollLeftVel:null,scrollIntervalId:null,scrollSensitivity:30,scrollSpeed:200,scrollIntervalMs:50,initAutoScroll:function(){var t=this.scrollEl;this.isAutoScroll=this.options.scroll&&t&&!t.is(window)&&!t.is(document),this.isAutoScroll&&this.listenTo(t,"scroll",yt(this.handleDebouncedScroll,100))},destroyAutoScroll:function(){this.endAutoScroll(),this.isAutoScroll&&this.stopListeningTo(this.scrollEl,"scroll")},computeScrollBounds:function(){this.isAutoScroll&&(this.scrollBounds=d(this.scrollEl))},updateAutoScroll:function(t){var e,n,i,r,s=this.scrollSensitivity,o=this.scrollBounds,a=0,l=0;o&&(e=(s-(E(t)-o.top))/s,n=(s-(o.bottom-E(t)))/s,i=(s-(b(t)-o.left))/s,r=(s-(o.right-b(t)))/s,e>=0&&e<=1?a=e*this.scrollSpeed*-1:n>=0&&n<=1&&(a=n*this.scrollSpeed),i>=0&&i<=1?l=i*this.scrollSpeed*-1:r>=0&&r<=1&&(l=r*this.scrollSpeed)),this.setScrollVel(a,l)},setScrollVel:function(t,e){this.scrollTopVel=t,this.scrollLeftVel=e,this.constrainScrollVel(),!this.scrollTopVel&&!this.scrollLeftVel||this.scrollIntervalId||(this.scrollIntervalId=setInterval(mt(this,"scrollIntervalFunc"),this.scrollIntervalMs))},constrainScrollVel:function(){var t=this.scrollEl;this.scrollTopVel<0?t.scrollTop()<=0&&(this.scrollTopVel=0):this.scrollTopVel>0&&t.scrollTop()+t[0].clientHeight>=t[0].scrollHeight&&(this.scrollTopVel=0),this.scrollLeftVel<0?t.scrollLeft()<=0&&(this.scrollLeftVel=0):this.scrollLeftVel>0&&t.scrollLeft()+t[0].clientWidth>=t[0].scrollWidth&&(this.scrollLeftVel=0)},scrollIntervalFunc:function(){var t=this.scrollEl,e=this.scrollIntervalMs/1e3;this.scrollTopVel&&t.scrollTop(t.scrollTop()+this.scrollTopVel*e),this.scrollLeftVel&&t.scrollLeft(t.scrollLeft()+this.scrollLeftVel*e),this.constrainScrollVel(),this.scrollTopVel||this.scrollLeftVel||this.endAutoScroll()},endAutoScroll:function(){this.scrollIntervalId&&(clearInterval(this.scrollIntervalId),this.scrollIntervalId=null,this.handleScrollEnd())},handleDebouncedScroll:function(){this.scrollIntervalId||this.handleScrollEnd()},handleScrollEnd:function(){}});var ye=me.extend({component:null,origHit:null,hit:null,coordAdjust:null,constructor:function(t,e){me.call(this,e),this.component=t},handleInteractionStart:function(t){var e,n,i,r=this.subjectEl;this.component.hitsNeeded(),this.computeScrollBounds(),t?(n={left:b(t),top:E(t)},i=n,r&&(e=d(r),i=x(i,e)),this.origHit=this.queryHit(i.left,i.top),r&&this.options.subjectCenter&&(this.origHit&&(e=R(this.origHit,e)||e),i=I(e)),this.coordAdjust=k(i,n)):(this.origHit=null,this.coordAdjust=null),me.prototype.handleInteractionStart.apply(this,arguments)},handleDragStart:function(t){var e;me.prototype.handleDragStart.apply(this,arguments),(e=this.queryHit(b(t),E(t)))&&this.handleHitOver(e)},handleDrag:function(t,e,n){var i;me.prototype.handleDrag.apply(this,arguments),i=this.queryHit(b(n),E(n)),Ht(i,this.hit)||(this.hit&&this.handleHitOut(),i&&this.handleHitOver(i))},handleDragEnd:function(){this.handleHitDone(),me.prototype.handleDragEnd.apply(this,arguments)},handleHitOver:function(t){var e=Ht(t,this.origHit);this.hit=t,this.trigger("hitOver",this.hit,e,this.origHit)},handleHitOut:function(){this.hit&&(this.trigger("hitOut",this.hit),this.handleHitDone(),this.hit=null)},handleHitDone:function(){this.hit&&this.trigger("hitDone",this.hit)},handleInteractionEnd:function(){me.prototype.handleInteractionEnd.apply(this,arguments),this.origHit=null,this.hit=null,this.component.hitsNotNeeded()},handleScrollEnd:function(){me.prototype.handleScrollEnd.apply(this,arguments),this.isDragging&&(this.component.releaseHits(),this.component.prepareHits())},queryHit:function(t,e){return this.coordAdjust&&(t+=this.coordAdjust.left,e+=this.coordAdjust.top),this.component.queryHit(t,e)}});Zt.touchMouseIgnoreWait=500;var we=bt.extend(ge,fe,{isTouching:!1,mouseIgnoreDepth:0,handleScrollProxy:null,bind:function(){var e=this;this.listenTo(t(document),{touchstart:this.handleTouchStart,touchcancel:this.handleTouchCancel,touchend:this.handleTouchEnd,mousedown:this.handleMouseDown,mousemove:this.handleMouseMove,mouseup:this.handleMouseUp,click:this.handleClick,selectstart:this.handleSelectStart,contextmenu:this.handleContextMenu}),window.addEventListener("touchmove",this.handleTouchMoveProxy=function(n){e.handleTouchMove(t.Event(n))},{passive:!1}),window.addEventListener("scroll",this.handleScrollProxy=function(n){e.handleScroll(t.Event(n))},!0)},unbind:function(){this.stopListeningTo(t(document)),window.removeEventListener("touchmove",this.handleTouchMoveProxy),window.removeEventListener("scroll",this.handleScrollProxy,!0)},handleTouchStart:function(t){this.stopTouch(t,!0),this.isTouching=!0,this.trigger("touchstart",t)},handleTouchMove:function(t){this.isTouching&&this.trigger("touchmove",t)},handleTouchCancel:function(t){this.isTouching&&(this.trigger("touchcancel",t),this.stopTouch(t))},handleTouchEnd:function(t){this.stopTouch(t)},handleMouseDown:function(t){this.shouldIgnoreMouse()||this.trigger("mousedown",t)},handleMouseMove:function(t){this.shouldIgnoreMouse()||this.trigger("mousemove",t)},handleMouseUp:function(t){this.shouldIgnoreMouse()||this.trigger("mouseup",t)},handleClick:function(t){this.shouldIgnoreMouse()||this.trigger("click",t)},handleSelectStart:function(t){this.trigger("selectstart",t)},handleContextMenu:function(t){this.trigger("contextmenu",t)},handleScroll:function(t){this.trigger("scroll",t)},stopTouch:function(t,e){this.isTouching&&(this.isTouching=!1,this.trigger("touchend",t),e||this.startTouchMouseIgnore())},startTouchMouseIgnore:function(){var t=this,e=Zt.touchMouseIgnoreWait;e&&(this.mouseIgnoreDepth++,setTimeout(function(){t.mouseIgnoreDepth--},e))},shouldIgnoreMouse:function(){return this.isTouching||Boolean(this.mouseIgnoreDepth)}});!function(){var t=null,e=0;we.get=function(){return t||(t=new we,t.bind()),t},we.needed=function(){we.get(),e++},we.unneeded=function(){--e||(t.unbind(),t=null)}}();var Se=bt.extend(ge,{options:null,sourceEl:null,el:null,parentEl:null,top0:null,left0:null,y0:null,x0:null,topDelta:null,leftDelta:null,isFollowing:!1,isHidden:!1,isAnimating:!1,constructor:function(e,n){this.options=n=n||{},this.sourceEl=e,this.parentEl=n.parentEl?t(n.parentEl):e.parent()},start:function(e){this.isFollowing||(this.isFollowing=!0,this.y0=E(e),this.x0=b(e),this.topDelta=0,this.leftDelta=0,this.isHidden||this.updatePosition(),D(e)?this.listenTo(t(document),"touchmove",this.handleMove):this.listenTo(t(document),"mousemove",this.handleMove))},stop:function(e,n){function i(){r.isAnimating=!1,r.removeElement(),r.top0=r.left0=null,n&&n()}var r=this,s=this.options.revertDuration;this.isFollowing&&!this.isAnimating&&(this.isFollowing=!1,this.stopListeningTo(t(document)),e&&s&&!this.isHidden?(this.isAnimating=!0,this.el.animate({top:this.top0,left:this.left0},{duration:s,complete:i})):i())},getEl:function(){var t=this.el;return t||(t=this.el=this.sourceEl.clone().addClass(this.options.additionalClass||"").css({position:"absolute",visibility:"",display:this.isHidden?"none":"",margin:0,right:"auto",bottom:"auto",width:this.sourceEl.width(),height:this.sourceEl.height(),opacity:this.options.opacity||"",zIndex:this.options.zIndex}),t.addClass("fc-unselectable"),t.appendTo(this.parentEl)),t},removeElement:function(){this.el&&(this.el.remove(),this.el=null)},updatePosition:function(){var t,e;this.getEl(),null===this.top0&&(t=this.sourceEl.offset(),e=this.el.offsetParent().offset(),this.top0=t.top-e.top,this.left0=t.left-e.left),this.el.css({top:this.top0+this.topDelta,left:this.left0+this.leftDelta})},handleMove:function(t){this.topDelta=E(t)-this.y0,this.leftDelta=b(t)-this.x0,this.isHidden||this.updatePosition()},hide:function(){this.isHidden||(this.isHidden=!0,this.el&&this.el.hide())},show:function(){this.isHidden&&(this.isHidden=!1,this.updatePosition(),this.getEl().show())}}),be=Zt.Grid=bt.extend(ge,{hasDayInteractions:!0,view:null,isRTL:null,start:null,end:null,el:null,elsByFill:null,eventTimeFormat:null,displayEventTime:null,displayEventEnd:null,minResizeDuration:null,largeUnit:null,dayClickListener:null,daySelectListener:null,segDragListener:null,segResizeListener:null,externalDragListener:null,constructor:function(t){this.view=t,this.isRTL=t.opt("isRTL"),this.elsByFill={},this.dayClickListener=this.buildDayClickListener(),this.daySelectListener=this.buildDaySelectListener()},computeEventTimeFormat:function(){return this.view.opt("smallTimeFormat")},computeDisplayEventTime:function(){return!0},computeDisplayEventEnd:function(){return!0},setRange:function(t){this.start=t.start.clone(),this.end=t.end.clone(),this.rangeUpdated(),this.processRangeOptions()},rangeUpdated:function(){},processRangeOptions:function(){var t,e,n=this.view;this.eventTimeFormat=n.opt("eventTimeFormat")||n.opt("timeFormat")||this.computeEventTimeFormat(),t=n.opt("displayEventTime"),null==t&&(t=this.computeDisplayEventTime()),e=n.opt("displayEventEnd"),null==e&&(e=this.computeDisplayEventEnd()),this.displayEventTime=t,this.displayEventEnd=e},spanToSegs:function(t){},diffDates:function(t,e){return this.largeUnit?G(t,e,this.largeUnit):F(t,e)},hitsNeededDepth:0,hitsNeeded:function(){this.hitsNeededDepth++||this.prepareHits()},hitsNotNeeded:function(){this.hitsNeededDepth&&!--this.hitsNeededDepth&&this.releaseHits()},prepareHits:function(){},releaseHits:function(){},queryHit:function(t,e){},getSafeHitSpan:function(t){var e=this.getHitSpan(t);return Q(e,this.view.activeRange)?e:null},getHitSpan:function(t){},getHitEl:function(t){},setElement:function(t){this.el=t,this.hasDayInteractions&&(T(t),this.bindDayHandler("touchstart",this.dayTouchStart),this.bindDayHandler("mousedown",this.dayMousedown)),this.bindSegHandlers(),this.bindGlobalHandlers()},bindDayHandler:function(e,n){var i=this;this.el.on(e,function(e){if(!t(e.target).is(i.segSelector+","+i.segSelector+" *,.fc-more,a[data-goto]"))return n.call(i,e)})},removeElement:function(){this.unbindGlobalHandlers(),this.clearDragListeners(),this.el.remove()},renderSkeleton:function(){},renderDates:function(){},unrenderDates:function(){},bindGlobalHandlers:function(){this.listenTo(t(document),{dragstart:this.externalDragStart,sortstart:this.externalDragStart})},unbindGlobalHandlers:function(){this.stopListeningTo(t(document))},dayMousedown:function(t){var e=this.view;we.get().shouldIgnoreMouse()||(this.dayClickListener.startInteraction(t),e.opt("selectable")&&this.daySelectListener.startInteraction(t,{distance:e.opt("selectMinDistance")}))},dayTouchStart:function(t){var e,n=this.view;n.isSelected||n.selectedEvent||(e=n.opt("selectLongPressDelay"),null==e&&(e=n.opt("longPressDelay")),this.dayClickListener.startInteraction(t),n.opt("selectable")&&this.daySelectListener.startInteraction(t,{delay:e}))},buildDayClickListener:function(){var t,e=this,n=this.view,i=new ye(this,{scroll:n.opt("dragScroll"),interactionStart:function(){t=i.origHit},hitOver:function(e,n,i){n||(t=null)},hitOut:function(){t=null},interactionEnd:function(i,r){var s;!r&&t&&(s=e.getSafeHitSpan(t))&&n.triggerDayClick(s,e.getHitEl(t),i)}});return i.shouldCancelTouchScroll=!1,i.scrollAlwaysKills=!0,i},buildDaySelectListener:function(){var t,e=this,n=this.view;return new ye(this,{scroll:n.opt("dragScroll"),interactionStart:function(){t=null},dragStart:function(){n.unselect()},hitOver:function(n,i,r){var o,a;r&&(o=e.getSafeHitSpan(r),a=e.getSafeHitSpan(n),t=o&&a?e.computeSelection(o,a):null,t?e.renderSelection(t):!1===t&&s())},hitOut:function(){t=null,e.unrenderSelection()},hitDone:function(){o()},interactionEnd:function(e,i){!i&&t&&n.reportSelection(t,e)}})},clearDragListeners:function(){this.dayClickListener.endInteraction(),this.daySelectListener.endInteraction(),this.segDragListener&&this.segDragListener.endInteraction(),this.segResizeListener&&this.segResizeListener.endInteraction(),this.externalDragListener&&this.externalDragListener.endInteraction()},renderEventLocationHelper:function(t,e){var n=this.fabricateHelperEvent(t,e);return this.renderHelper(n,e)},fabricateHelperEvent:function(t,e){var n=e?rt(e.event):{};return n.start=t.start.clone(),n.end=t.end?t.end.clone():null,n.allDay=null,this.view.calendar.normalizeEventDates(n),n.className=(n.className||[]).concat("fc-helper"),e||(n.editable=!1),n},renderHelper:function(t,e){},unrenderHelper:function(){},renderSelection:function(t){this.renderHighlight(t)},unrenderSelection:function(){this.unrenderHighlight()},computeSelection:function(t,e){var n=this.computeSelectionSpan(t,e);return!(n&&!this.view.calendar.isSelectionSpanAllowed(n))&&n},computeSelectionSpan:function(t,e){var n=[t.start,t.end,e.start,e.end];return n.sort(pt),{start:n[0].clone(),end:n[3].clone()}},renderHighlight:function(t){this.renderFill("highlight",this.spanToSegs(t))},unrenderHighlight:function(){this.unrenderFill("highlight")},highlightSegClasses:function(){return["fc-highlight"]},renderBusinessHours:function(){},unrenderBusinessHours:function(){},getNowIndicatorUnit:function(){},renderNowIndicator:function(t){},unrenderNowIndicator:function(){},renderFill:function(t,e){},unrenderFill:function(t){var e=this.elsByFill[t];e&&(e.remove(),delete this.elsByFill[t])},renderFillSegEls:function(e,n){var i,r=this,s=this[e+"SegEl"],o="",a=[];if(n.length){for(i=0;i "},getDayClasses:function(t,e){var n,i=this.view,r=[];return Z(t,i.activeRange)?(r.push("fc-"+Kt[t.day()]),1==i.currentRangeAs("months")&&t.month()!=i.currentRange.start.month()&&r.push("fc-other-month"),n=i.calendar.getNow(),t.isSame(n,"day")?(r.push("fc-today"),!0!==e&&r.push(i.highlightStateClass)):t *",mousedOverSeg:null,isDraggingSeg:!1,isResizingSeg:!1,isDraggingExternal:!1,segs:null,renderEvents:function(t){var e,n=[],i=[];for(e=0;ea&&o.push({start:a,end:n.start}),n.end>a&&(a=n.end);return a=e.length?e[e.length-1]+1:e[n]},computeColHeadFormat:function(){return this.rowCnt>1||this.colCnt>10?"ddd":this.colCnt>1?this.view.opt("dayOfMonthFormat"):"dddd"},sliceRangeByRow:function(t){var e,n,i,r,s,o=this.daysPerRow,a=this.view.computeDayRange(t),l=this.getDateDayIndex(a.start),u=this.getDateDayIndex(a.end.clone().subtract(1,"days")),h=[];for(e=0;e